home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-10-02 | 124.3 KB | 4,778 lines | [TEXT/gamI] |
- /*---------------------------------------------------------------------------*/
-
- /* file: "_kernel.s" */
-
- /*-----------------------------------------------------------------------------
-
- GAMBIT kernel.
-
- This file should be assembled with 'AS' to produce '_kernel.O'.
- 'kernel.O' is the first object file to be loaded into the system. The
- first object in the file (which must be a procedure) is responsible
- for setting up the runtime context and running all the other modules
- that were loaded. This procedure is special because it uses the C
- calling convention.
-
- -----------------------------------------------------------------------------*/
-
-
- /* Main parameters: */
-
-
- /* Define MIN_C_CONTEXT if C's context is kept only in A5, A6 and SP */
-
- #define MIN_C_CONTEXT
-
-
- /* Define DETERMINE_IS_STRICT if 'determine!' should touch its second arg */
-
- #define DETERMINE_IS_STRICT
-
- #define LIGITIMACY
-
-
- /* Define MESSAGE_PASSING_STEAL if tasks are stolen with message passing */
- /* protocol (otherwise, shared memory protocol is used) */
-
- #define MESSAGE_PASSING_STEAL
-
-
- /* Define SYNCHRONOUS_STEAL if thief processor waits for reply from victim */
-
- #define SYNCHRONOUS_STEAL
-
-
- /* Define MAINTAIN_TASK_STATUS if the status of the tasks should be updated. */
- /* There are 4 possible states: READY to run (status=pointer to queue entry),*/
- /* RUNNING (status=pointer to processor state), WAITING (status=null) and */
- /* DEAD (status=false). */
-
- #define MAINTAIN_TASK_STATUS
-
-
- /* MAX_FRAME_CHUNK_SIZE is the maximum number of slots in a stack frame */
- /* chunk (i.e. a group of contiguous stack frames) */
-
- #define MAX_FRAME_CHUNK_SIZE 25
- #define MAX_FRAME_CHUNK_SIZEzzz 1024
-
-
- /* MAX_TASK_FRAME_CHUNK_SIZE is the maximum number of slots in a stack frame */
- /* chunk which contains lazy tasks. MIN_VICTIM_TASKS is the minimum number */
- /* of lazy tasks to leave the victim when there is a steal of more than one */
- /* task. */
-
- #define MAX_TASK_FRAME_CHUNK_SIZEzzz 25
- #define MIN_VICTIM_TASKSzzz 20
- #define MAX_TASK_FRAME_CHUNK_SIZE 25
- #define MIN_VICTIM_TASKS 20
-
-
- /* Interrupt checking latencies (1 = soonest possible) */
-
- #define INTR_LATENCY_AFTER_STEAL 5
-
-
- /*---------------------------------------------------------------------------*/
-
-
- /* DYN_ENV_FS is the size of a dynamic environment frame */
-
- #define DYN_ENV_FS 2
-
-
- /*---------------------------------------------------------------------------*/
-
-
- /* String concatenation depends on style of preprocessing... */
- #ifdef __STDC__
- #define MAKE_LBL(x,y)y##__##x
- #else
- #define QUOTE(x)x
- #define MAKE_LBL(x,y)QUOTE(QUOTE(y)__)x
- #endif
-
-
- #ifdef hpux
-
- /* HPUX assembler definitions... */
-
- #define OBJECT_FILE_BEGIN _object_file_begin: global _object_file_begin
- #define OBJECT_FILE_END _object_file_end: global _object_file_end
-
- #define DISP(r,n) n(r)
- #define INXW(r,i,n) n(r,i.w)
- #define PC_IND(lab) LBL(lab)(%pc)
- #define ALIGN2 lalign 2
- #define ALIGN4 lalign 4
- #define ALIGN8 lalign 8
- #define SET(a,b) set a,b
- #define CONST(n) LBL($consts)+(n*4)(%pc)
- #define REG(x) %x
- #define IMM(x) &x
- #define PINC(r) (r)+
- #define PDEC(r) -(r)
- #define IND(r) (r)
- #define BYTE byte
- #define WORD short
- #define LONG long
- #define ASCIZ asciz
- #define movb move.b
- #define movw move.w
- #define movl move.l
- #define extl ext.l
- #define addw add.w
- #define addl add.l
- #define addqw addq.w
- #define addql addq.l
- #define subw sub.w
- #define subl sub.l
- #define subqw subq.w
- #define subql subq.l
- #define negl neg.l
- #define clrb clr.b
- #define clrl clr.l
- #define muluw mulu.w
- #define notw not.w
- #define andw and.w
- #define andl and.l
- #define aslw asl.w
- #define asll asl.l
- #define asrw asr.w
- #define asrl asr.l
- #define lsrw lsr.w
- #define lsrl lsr.l
- #define tstw tst.w
- #define tstl tst.l
- #define CMPW(x,y) cmp.w y,x
- #define CMPL(x,y) cmp.l y,x
- #define DBRA(r,lab) dbra r,LBL(lab)
- #define BRAS(lab) bra.b LBL(lab)
- #define BEQS(lab) beq.b LBL(lab)
- #define BEQW(lab) beq.w LBL(lab)
- #define BNES(lab) bne.b LBL(lab)
- #define BNEW(lab) bne.w LBL(lab)
- #define BMIS(lab) bmi.b LBL(lab)
- #define BMIW(lab) bmi.w LBL(lab)
- #define BPLS(lab) bpl.b LBL(lab)
- #define BPLW(lab) bpl.w LBL(lab)
- #define BLES(lab) ble.b LBL(lab)
- #define BLEW(lab) ble.w LBL(lab)
- #define BGES(lab) bge.b LBL(lab)
- #define BCCS(lab) bcc.b LBL(lab)
- #define BCCW(lab) bcc.w LBL(lab)
- #define BCSS(lab) bcs.b LBL(lab)
- #define BCSW(lab) bcs.w LBL(lab)
- #define BLSS(lab) bls.b LBL(lab)
- #define BHIS(lab) bhi.b LBL(lab)
- #define BGTS(lab) bgt.b LBL(lab)
- #define BGTW(lab) bgt.w LBL(lab)
- #define BLTS(lab) blt.b LBL(lab)
- #define BRAW(lab) bra.w LBL(lab)
- #define BSRW(lab) bsr.w LBL(lab)
-
- #define fmovel fmov.l
- #define FPCR %fpcr
- #define FPSR %fpsr
-
- #else
-
- /* SUN3 assembler definitions... */
-
- #define OBJECT_FILE_BEGIN _object_file_begin: .globl _object_file_begin
- #define OBJECT_FILE_END _object_file_end: .globl _object_file_end
-
- #define DISP(r,n) r@(n:w)
- #define INXW(r,i,n) r@(n:w,i:w)
- #define PC_IND(lab) pc@(-2-(.-LBL(lab)):w)
- #define ALIGN2 .even
- #define ALIGN4 .=(.-_object_file_begin+3)/4*4
- #define ALIGN8 .=(.-_object_file_begin+7)/8*8
- #define SET(a,b) a = b
- #define CONST(n) pc@((n*4)-2-(.-LBL($consts)):w)
- #define REG(r) r
- #define IMM(x) #x
- #define PINC(r) r@+
- #define PDEC(r) r@-
- #define IND(r) r@
- #define BYTE .byte
- #define WORD .word
- #define LONG .long
- #define ASCIZ .asciz
- #define muluw mulu
- #define CMPW(x,y) cmpw x,y
- #define CMPL(x,y) cmpl x,y
- #define DBRA(r,lab) dbra r,LBL(lab)
- #define BRAS(lab) BYTE 0x60,LBL(lab)-.-2
- #define BEQS(lab) BYTE 0x67,LBL(lab)-.-2
- #define BEQW(lab) WORD 0x6700,LBL(lab)-.-2
- #define BNES(lab) BYTE 0x66,LBL(lab)-.-2
- #define BNEW(lab) WORD 0x6600,LBL(lab)-.-2
- #define BMIS(lab) BYTE 0x6b,LBL(lab)-.-2
- #define BMIW(lab) WORD 0x6b00,LBL(lab)-.-2
- #define BPLS(lab) BYTE 0x6a,LBL(lab)-.-2
- #define BPLW(lab) WORD 0x6a00,LBL(lab)-.-2
- #define BLES(lab) BYTE 0x6f,LBL(lab)-.-2
- #define BLEW(lab) WORD 0x6f00,LBL(lab)-.-2
- #define BGES(lab) BYTE 0x6c,LBL(lab)-.-2
- #define BCCS(lab) BYTE 0x64,LBL(lab)-.-2
- #define BCCW(lab) WORD 0x6400,LBL(lab)-.-2
- #define BCSS(lab) BYTE 0x65,LBL(lab)-.-2
- #define BCSW(lab) WORD 0x6500,LBL(lab)-.-2
- #define BLSS(lab) BYTE 0x63,LBL(lab)-.-2
- #define BHIS(lab) BYTE 0x62,LBL(lab)-.-2
- #define BGTS(lab) BYTE 0x6e,LBL(lab)-.-2
- #define BGTW(lab) WORD 0x6e00,LBL(lab)-.-2
- #define BLTS(lab) BYTE 0x6d,LBL(lab)-.-2
- #define BRAW(lab) WORD 0x6000,LBL(lab)-.-2
- #define BSRW(lab) WORD 0x6100,LBL(lab)-.-2
-
- #define FPCR fpcr
- #define FPSR fpsr
-
- .data
-
- #endif
-
-
- /* General definitions... */
-
-
- #define PRIMITIVE(name) \
- %NEWLINE% LONG PRIM_PROC+(INDEX_MASK*8) \
- %NEWLINE% ASCIZ name \
- %NEWLINE% ALIGN2
-
- #define BEGIN(name) \
- %NEWLINE% LONG PRIM_PROC_PREFIX \
- %NEWLINE% WORD INDEX_MASK \
- %NEWLINE% ASCIZ name \
- %NEWLINE% ALIGN2 \
- %NEWLINE% WORD LBL($header) \
- %NEWLINE% ALIGN8 \
- %NEWLINE% WORD LBL($code_len_tag) \
- %NEWLINE%LBL($entry):
-
- #define CONSTS(n) \
- %NEWLINE% ALIGN4 \
- %NEWLINE%LBL($consts): \
- %NEWLINE% WORD END_OF_CODE_TAG \
- %NEWLINE% SET(LBL($nb_consts),n+2)
-
- #define END \
- %NEWLINE% LONG SCM_false \
- %NEWLINE% LONG LBL($nb_consts)*8 \
- %NEWLINE% SET(LBL($code_len),LBL($consts)-LBL($entry)) \
- %NEWLINE% SET(LBL($code_len_tag),LBL($code_len)/2) \
- %NEWLINE% SET(LBL($header),HEADER(LBL($nb_consts)*4)+LBL($code_len)-2)
-
- #define HEADER(l) ((l)+0x8000)
- #define GLOB_OFFS(x) (((x)*8)-(MAX_NB_GLOBALS*10)-(NB_TRAPS*8)+0x8000)
- #define TRAP_OFFS(x) (((x)-NB_TRAPS)*8+0x8000)
- #define STAT_OFFS(x) (((x)-MAX_NB_STATS)*4)
- #define SLOT(x) ((x)*4)
-
- #define RETURN(lab,fs,link) \
- %NEWLINE% ALIGN8 \
- %NEWLINE% LONG 0 \
- %NEWLINE% WORD (fs)*4 \
- %NEWLINE% WORD ((fs)-(link))*4 \
- %NEWLINE% WORD -0x8002-(.-LBL($entry)) \
- %NEWLINE%LBL(lab)
-
- #define RETURN_LAZY(lab,fs,link) \
- %NEWLINE% ALIGN8 \
- %NEWLINE% LONG 0 \
- %NEWLINE% WORD -0x8000+(fs)*4 \
- %NEWLINE% WORD ((fs)-(link))*4 \
- %NEWLINE% WORD -0x8002-(.-LBL($entry)) \
- %NEWLINE%LBL(lab)
-
- #define SUBPROC(lab) \
- %NEWLINE% ALIGN8 \
- %NEWLINE% WORD -0x8002-(.-LBL($entry)) \
- %NEWLINE%LBL(lab)
-
- #define WRONG_NB_ARGS(x,n,lab) \
- %NEWLINE% jsr DISP(TABLE_REG,TRAP_OFFS(x)) \
- %NEWLINE% WORD n \
- %NEWLINE% WORD .-LBL(lab)
-
- #define TRAP(x,lab,fs,link) \
- %NEWLINE% BRAS( lab) \
- %NEWLINE% nop \
- %NEWLINE% ALIGN8 \
- %NEWLINE%LBL(lab): \
- %NEWLINE% jsr DISP(TABLE_REG,TRAP_OFFS(x)) \
- %NEWLINE% WORD fs*4 \
- %NEWLINE% WORD (fs-link)*4 \
- %NEWLINE% WORD -0x8002-(.-LBL($entry))
-
- #define GET_TRAP_RETURN(nb_args) \
- %NEWLINE% GET_TRAP_RET(nb_args) \
- %NEWLINE% addql IMM(SCM_type_PROCEDURE),DTEMP1
-
- #define GET_TRAP_RET(nb_args) \
- %NEWLINE% moveq IMM(11+(nb_args*2)),DTEMP1 \
- %NEWLINE% addl PINC(SP),DTEMP1 \
- %NEWLINE% andw IMM(-8),DTEMP1
-
- #define MOVE_ARGS_TO_STACK(arg_count) \
- %NEWLINE% movw arg_count,DTEMP1 \
- %NEWLINE% BPLS( not_1_arg) \
- %NEWLINE% moveq IMM(1),DTEMP1 /* 1 arg passed */ \
- %NEWLINE% movl PVM1_REG,PDEC(SP) \
- %NEWLINE% BRAS( args_pushed) \
- %NEWLINE%LBL(not_1_arg): \
- %NEWLINE% BNES( not_1_or_2_args) \
- %NEWLINE% moveq IMM(2),DTEMP1 /* 2 args passed */ \
- %NEWLINE% movl PVM1_REG,PDEC(SP) \
- %NEWLINE% movl PVM2_REG,PDEC(SP) \
- %NEWLINE% BRAS( args_pushed) \
- %NEWLINE%LBL(not_1_or_2_args): \
- %NEWLINE% subqw IMM(1),DTEMP1 \
- %NEWLINE% BEQS( args_pushed) \
- %NEWLINE% movl PVM1_REG,PDEC(SP) /* 3 or more args passed */\
- %NEWLINE% movl PVM2_REG,PDEC(SP) \
- %NEWLINE% movl PVM3_REG,PDEC(SP) \
- %NEWLINE%LBL(args_pushed):
-
- #define RESET_STACK \
- %NEWLINE% movl DISP(PSTATE_REG,SLOT(STACK_TOP)),SP \
- %NEWLINE% movl DISP(PSTATE_REG,SLOT(Q_BOT)),LTQ_TAIL_REG \
- %NEWLINE% movl SP,PINC(LTQ_TAIL_REG) \
- %NEWLINE% movl LTQ_TAIL_REG,DISP(PSTATE_REG,SLOT(LTQ_HEAD)) \
- %NEWLINE% movl DISP(PSTATE_REG,SLOT(Q_TOP)),ATEMP1 \
- %NEWLINE% movl SP,PDEC(ATEMP1) \
- %NEWLINE% movl ATEMP1,DISP(PSTATE_REG,SLOT(DEQ_TAIL)) \
- %NEWLINE% movl ATEMP1,DISP(PSTATE_REG,SLOT(DEQ_HEAD))
-
- #define MAKE_TEMP_TASK \
- %NEWLINE% clrl PDEC(HEAP_REG) /* Make legitimacy PH */ \
- %NEWLINE% clrl PDEC(HEAP_REG) \
- %NEWLINE% movl NULL_REG,PDEC(HEAP_REG) \
- %NEWLINE% lea DISP(HEAP_REG,SCM_type_PLACEHOLDER-4),ATEMP2 \
- %NEWLINE% movl ATEMP2,PDEC(HEAP_REG) \
- %NEWLINE% clrl PDEC(HEAP_REG) /* Make value PH */ \
- %NEWLINE% clrl PDEC(HEAP_REG) \
- %NEWLINE% movl NULL_REG,PDEC(HEAP_REG) \
- %NEWLINE% lea DISP(HEAP_REG,SCM_type_PLACEHOLDER-4),ATEMP1 \
- %NEWLINE% movl ATEMP1,PDEC(HEAP_REG) \
- %NEWLINE% clrl PDEC(HEAP_REG) /* Make task */ \
- %NEWLINE% clrl PDEC(HEAP_REG) \
- %NEWLINE% movl FALSE_REG,PDEC(HEAP_REG) \
- %NEWLINE% movl ATEMP1,PDEC(HEAP_REG) \
- %NEWLINE% movl ATEMP1,PDEC(HEAP_REG) \
- %NEWLINE% movl ATEMP2,PDEC(HEAP_REG) \
- %NEWLINE% clrl PDEC(HEAP_REG) \
- %NEWLINE% clrl PDEC(HEAP_REG) \
- %NEWLINE% clrl PDEC(HEAP_REG) \
- %NEWLINE% movl IMM(TASK_SIZE*0x400+(SCM_subtype_TASK*8)),PDEC(HEAP_REG) \
- %NEWLINE% lea DISP(HEAP_REG,SCM_type_SUBTYPED),ATEMP1 \
- %NEWLINE% movl ATEMP1,DISP(PSTATE_REG,SLOT(TEMP_TASK))
-
- #ifdef STATS
-
- #define STAT(n,x) \
- %NEWLINE% addql IMM(n),DISP(PSTATE_REG,STAT_OFFS(x))
-
- #define STAT_DTEMP1(x) \
- %NEWLINE% addl DTEMP1,DISP(PSTATE_REG,STAT_OFFS(x))
-
- #else
-
- #define STAT(n,x)
- #define STAT_DTEMP1(x)
-
- #endif
-
- #ifdef butterfly
-
- #define ATOMCTA16 0 = a0, mask/incr = d1, adr = d0
- #define ATOMADD32 1
- #define ATOMAND32 2
- #define ATOMIOR32 3
-
- #define DO_ATOMIC \
- %NEWLINE% trap IMM(0xe)
-
- #define DO_BTRANSFER \
- %NEWLINE% trap IMM(0xc)
-
- #define DO_GETRTC \
- %NEWLINE% trap IMM(0xd)
-
- #define ADD_TO_DTEMP1() \
- %NEWLINE% /* d0 = address, d1 = value */\
- %NEWLINE% movw IMM(ATOMADD32),PVM0_REG /* a0 = atomadd32 command */\
- %NEWLINE% DO_ATOMIC /* d0,a0,a1 not preserved */
-
- #define READ_AND_CLEAR_DTEMP1 \
- %NEWLINE% /* d0 = address */\
- %NEWLINE% movw IMM(ATOMAND32),PVM0_REG /* a0 = atomand32 command */\
- %NEWLINE% moveq IMM(0),PVM1_REG /* d1 = mask */\
- %NEWLINE% DO_ATOMIC /* d0,a0,a1 not preserved */
-
- #define READ_AND_SET_DTEMP1 \
- %NEWLINE% /* d0 = address */\
- %NEWLINE% movw IMM(ATOMIOR32),PVM0_REG /* a0 = atomior32 command */\
- %NEWLINE% moveq IMM(-1),PVM1_REG /* d1 = mask */\
- %NEWLINE% DO_ATOMIC /* d0,a0,a1 not preserved */
-
- #define LOCK_ATEMP1(lab) \
- %NEWLINE% movl ATEMP1,PVM4_REG \
- %NEWLINE%LBL(lab): \
- %NEWLINE% movw IMM(ATOMIOR32),PVM0_REG /* a0 = atomior32 command */\
- %NEWLINE% movl PVM4_REG,DTEMP1 /* d0 = address */\
- %NEWLINE% moveq IMM(-1),PVM1_REG /* d1 = mask */\
- %NEWLINE% DO_ATOMIC /* d0,a0,a1 not preserved */\
- %NEWLINE% CMPL( DTEMP1,PVM1_REG) \
- %NEWLINE% BEQS( lab) \
- %NEWLINE% movl PVM4_REG,ATEMP1 \
-
- #define LOCK_ATEMP2(lab) \
- %NEWLINE%LBL(lab): \
- %NEWLINE% movw IMM(ATOMIOR32),PVM0_REG /* a0 = atomior32 command */\
- %NEWLINE% movl ATEMP2,DTEMP1 /* d0 = address */\
- %NEWLINE% moveq IMM(-1),PVM1_REG /* d1 = mask */\
- %NEWLINE% DO_ATOMIC /* d0,a0,a1 not preserved */\
- %NEWLINE% CMPL( DTEMP1,PVM1_REG) \
- %NEWLINE% BEQS( lab)
-
- #define BTRANSFER(lab) \
- %NEWLINE% DO_BTRANSFER /* a0 = src, d0 = dest, d1 = nb of bytes */\
- %NEWLINE% /* d0,d1,a1 not preserved */
-
- #ifdef ELOG
-
- #define LOG(event_num,lab) \
- %NEWLINE% DO_GETRTC /* d0 = real time clock value */ \
- %NEWLINE% movl DISP(PSTATE_REG,SLOT(ELOG_PTR)),ATEMP1 \
- %NEWLINE% CMPL( DISP(PSTATE_REG,SLOT(ELOG_BOT)),ATEMP1) \
- %NEWLINE% BEQS( lab) \
- %NEWLINE% movl DTEMP1,PDEC(ATEMP1) \
- %NEWLINE% movb IMM(event_num),IND(ATEMP1) \
- %NEWLINE% movl ATEMP1,DISP(PSTATE_REG,SLOT(ELOG_PTR)) \
- %NEWLINE%LBL(lab):
-
- #define PREV_LOG(n,lab) \
- %NEWLINE% DO_GETRTC /* d0 = real time clock value */ \
- %NEWLINE% movl DISP(PSTATE_REG,SLOT(ELOG_PTR)),ATEMP1 \
- %NEWLINE% CMPL( DISP(PSTATE_REG,SLOT(ELOG_BOT)),ATEMP1) \
- %NEWLINE% BEQS( lab) \
- %NEWLINE% movl DTEMP1,PDEC(ATEMP1) \
- %NEWLINE% movb DISP(ATEMP1,4*n),IND(ATEMP1) \
- %NEWLINE% movl ATEMP1,DISP(PSTATE_REG,SLOT(ELOG_PTR)) \
- %NEWLINE%LBL(lab):
-
- #else
-
- #define LOG(x,lab)
- #define PREV_LOG(x,lab)
-
- #endif
-
- #else
-
- #define ADD_TO_DTEMP1
-
- #define READ_AND_CLEAR_DTEMP1 \
- %NEWLINE% movl DTEMP1,ATEMP1 \
- %NEWLINE% movl IND(ATEMP1),DTEMP1 \
- %NEWLINE% clrl IND(ATEMP1)
-
- #define READ_AND_SET_DTEMP1 \
- %NEWLINE% movl DTEMP1,ATEMP1 \
- %NEWLINE% movl IND(ATEMP1),DTEMP1 \
- %NEWLINE% movl IMM(-1),IND(ATEMP1)
-
- #define LOCK_ATEMP1(lab) \
- %NEWLINE% movl IND(ATEMP1),DTEMP1
-
- #define LOCK_ATEMP2(lab) \
- %NEWLINE% movl IND(ATEMP2),DTEMP1
-
- #define BTRANSFER(lab) \
- %NEWLINE% movl DTEMP1,ATEMP1 \
- %NEWLINE% lsrl IMM(2),PVM1_REG \
- %NEWLINE% subql IMM(1),PVM1_REG \
- %NEWLINE%LBL(lab): \
- %NEWLINE% movl PINC(PVM0_REG),PINC(ATEMP1) \
- %NEWLINE% DBRA( PVM1_REG,lab)
-
- #define LOG(x,lab)
- #define PREV_LOG(x,lab)
-
- #endif
-
-
- #define WORK_REQUEST THIEF
-
-
- /* Registers... */
-
-
- #define PVM0_REG REG(a0)
- #define PVM1_REG REG(d1)
- #define PVM2_REG REG(d2)
- #define PVM3_REG REG(d3)
- #define PVM4_REG REG(d4)
- #define CLOSURE_REG REG(d4)
- #define INTR_TIMER_REG REG(d5)
- #define NULL_REG REG(d6)
- #define PLACEHOLDER_REG REG(d6)
- #define FALSE_REG REG(d7)
- #define PAIR_REG REG(d7)
-
- #define DTEMP1 REG(d0)
- #define ATEMP1 REG(a1)
- #define ATEMP2 REG(a2)
-
- #define HEAP_REG REG(a3)
- #define LTQ_TAIL_REG REG(a4)
- #define PSTATE_REG REG(a5)
- #define TABLE_REG REG(a6)
- #define SP REG(a7)
-
-
- /*---------------------------------------------------------------------------*/
-
- /* Start of kernel... */
-
- OBJECT_FILE_BEGIN
- WORD OFILE_VERSION_MAJOR /* Stamp with appropriate version */
- WORD OFILE_VERSION_MINOR
-
- /*---------------------------------------------------------------------------*/
-
- /*
-
- *** The first procedure (i.e. '###_kernel') is called from C as in:
- ***
- *** kernel_startup( table, pstate, os_M68881 );
-
- */
-
- #undef LBL
- #define LBL(x)MAKE_LBL(00,x)
-
- BEGIN("###_kernel")
-
- movl CONST(0),PVM0_REG /* jump to #_kernel.startup */
- jmp IND(PVM0_REG)
-
- /* Reserve space for saving C's context */
-
- LONG 0 /* C's D2 register */
- LONG 0 /* C's D3 register */
- LONG 0 /* C's D4 register */
- LONG 0 /* C's D5 register */
- LONG 0 /* C's D6 register */
- LONG 0 /* C's D7 register */
- LONG 0 /* C's A2 register */
- LONG 0 /* C's A3 register */
- LONG 0 /* C's A4 register */
- LONG 0 /* C's A5 register */
- LONG 0 /* C's A6 register */
- LONG 0 /* C's SP register */
-
- SET(C_D2,6)
- SET(C_D3,10)
- SET(C_D4,14)
- SET(C_D5,18)
- SET(C_D6,22)
- SET(C_D7,26)
- SET(C_A2,30)
- SET(C_A3,34)
- SET(C_A4,38)
- SET(C_A5,42)
- SET(C_A6,46)
- SET(C_SP,50)
-
- CONSTS(1)
- PRIMITIVE("###_kernel.startup")
- END
-
- /*---------------------------------------------------------------------------*/
-
- #undef LBL
- #define LBL(x)MAKE_LBL(01,x)
-
- BEGIN("###_kernel.trap_0")
-
- /* global_jump */
-
- movl IMM(SCM_false),FALSE_REG /* d7 was clobbered so restore it */
-
- movw DTEMP1,PDEC(SP) /* save argument count temporarily */
- movl ATEMP1,DTEMP1
-
- addl IMM((MAX_NB_GLOBALS*2)+(NB_TRAPS*8-0x8000)),DTEMP1
- subl TABLE_REG,DTEMP1
- asll IMM(2),DTEMP1
- addl TABLE_REG,DTEMP1
- subl IMM((MAX_NB_GLOBALS*10)+(NB_TRAPS*8-0x8000)),DTEMP1
-
- movl DTEMP1,ATEMP1
- movl PINC(ATEMP1),DTEMP1
-
- movl DTEMP1,ATEMP2
- addql IMM(SCM_type_PAIR-SCM_type_PROCEDURE),DTEMP1
- btst DTEMP1,PAIR_REG
- BNES( not_a_proc)
-
- movl ATEMP2,IND(ATEMP1) /* replace trap adr by procedure adr */
- movw PINC(SP),DTEMP1 /* restore argument count and set flags */
- jmp IND(ATEMP2) /* jump to procedure */
-
- LBL(not_a_proc):
- subql IMM(4),ATEMP1 /* compute 'global variable index' */
- addl IMM((MAX_NB_GLOBALS*10)+(NB_TRAPS*8-0x8000)),ATEMP1
- subl TABLE_REG,ATEMP1
-
- MOVE_ARGS_TO_STACK(PINC(SP))
-
- /* make room for 'global variable index' argument */
-
- movw DTEMP1,PVM1_REG
- movl SP,ATEMP2
- subql IMM(4),SP
- BRAS( loop_entry)
- LBL(loop):
- movl PINC(ATEMP2),DISP(ATEMP2,-8)
- LBL(loop_entry):
- DBRA( PVM1_REG,loop)
-
- movl ATEMP1,DISP(ATEMP2,-4)
- addqw IMM(1),DTEMP1
-
- movl CONST(0),ATEMP1 /* apply ##exception.global-jump */
- movl CONST(1),ATEMP2
- jmp IND(ATEMP2)
-
- CONSTS(2)
- PRIMITIVE("##exception.global-jump")
- PRIMITIVE("###_kernel.apply")
- END
-
- /*---------------------------------------------------------------------------*/
-
- #undef LBL
- #define LBL(x)MAKE_LBL(02,x)
-
- BEGIN("###_kernel.trap_1")
-
- /* touch d0 */
-
- movl DTEMP1,ATEMP2
-
- GET_TRAP_RETURN(0)
- movl DTEMP1,PVM0_REG
-
- LBL(touch):
- movl DISP(ATEMP2,SLOT(PH_VALUE)-SCM_type_PLACEHOLDER),DTEMP1
- CMPL( ATEMP2,DTEMP1)
- BNES( determined)
-
- LOG(EVENT_TOUCH_UNDET,log1)
-
- #ifdef DETERMINE_IS_STRICT
-
- movl CONST(0),ATEMP1
- jmp IND(ATEMP1) /* jump to ###_kernel.touch */
- LBL(determined):
-
- #else
-
- movl PVM0_REG,PDEC(SP)
- lea PC_IND(ret),PVM0_REG
- movl CONST(0),ATEMP1
- jmp IND(ATEMP1) /* jump to ###_kernel.touch */
- RETURN(ret,1,1):
- movl PINC(SP),PVM0_REG
- LBL(determined):
- btst DTEMP1,PLACEHOLDER_REG
- BNES( touched)
- movl DTEMP1,ATEMP2
- BRAS( touch)
- LBL(touched):
-
- #endif
-
- jmp IND(PVM0_REG)
-
- CONSTS(1)
- PRIMITIVE("###_kernel.touch")
- END
-
- /*---------------------------------------------------------------------------*/
-
- #undef LBL
- #define LBL(x)MAKE_LBL(03,x)
-
- BEGIN("###_kernel.trap_2")
-
- /* touch d1 */
-
- GET_TRAP_RETURN(0)
- movl DTEMP1,PVM0_REG
-
- LBL(touch):
- movl PVM1_REG,ATEMP2
- movl DISP(ATEMP2,SLOT(PH_VALUE)-SCM_type_PLACEHOLDER),PVM1_REG
- CMPL( ATEMP2,PVM1_REG)
- BNES( determined)
-
- LOG(EVENT_TOUCH_UNDET,log1)
-
- #ifdef DETERMINE_IS_STRICT
-
- movl CONST(0),ATEMP1
- jmp IND(ATEMP1) /* jump to ###_kernel.touch */
- LBL(determined):
-
- #else
-
- movl PVM0_REG,PDEC(SP)
- lea PC_IND(ret),PVM0_REG
- movl CONST(0),ATEMP1
- jmp IND(ATEMP1) /* jump to ###_kernel.touch */
- RETURN(ret,1,1):
- movl PINC(SP),PVM0_REG
- LBL(determined):
- btst PVM1_REG,PLACEHOLDER_REG
- BEQS( touch)
-
- #endif
-
- jmp IND(PVM0_REG)
-
- CONSTS(1)
- PRIMITIVE("###_kernel.touch")
- END
-
- /*---------------------------------------------------------------------------*/
-
- #undef LBL
- #define LBL(x)MAKE_LBL(04,x)
-
- BEGIN("###_kernel.trap_3")
-
- /* touch d2 */
-
- GET_TRAP_RETURN(0)
- movl DTEMP1,PVM0_REG
-
- LBL(touch):
- movl PVM2_REG,ATEMP2
- movl DISP(ATEMP2,SLOT(PH_VALUE)-SCM_type_PLACEHOLDER),PVM2_REG
- CMPL( ATEMP2,PVM2_REG)
- BNES( determined)
-
- LOG(EVENT_TOUCH_UNDET,log1)
-
- #ifdef DETERMINE_IS_STRICT
-
- movl CONST(0),ATEMP1
- jmp IND(ATEMP1) /* jump to ###_kernel.touch */
- LBL(determined):
-
- #else
-
- movl PVM0_REG,PDEC(SP)
- lea PC_IND(ret),PVM0_REG
- movl CONST(0),ATEMP1
- jmp IND(ATEMP1) /* jump to ### SP),DTEMP1
-
- CMPL( DTEMP1,HEAP_REG)
- subl DTEMP1,HEAP_REG /* allocate space and check heap overflow */
- BCSS( overflow_on_alloc)
- CMPL( DISP(PSTATE_REG,SLOT(HEAP_LIM)),HEAP_REG)
- BCCS( allocated)
- LBL(overflow_on_alloc):
- addl DTEMP1,HEAP_REG /* restore correct heap ptr */
-
- /* Then use a smaller heap margin and signal a heap overflow */
-
- movl DISP(PSTATE_REG,SLOT(HEAP_MARGIN)),DTEMP1
- BEQS( fatal_overflow)
-
- subl DTEMP1,DISP(PSTATE_REG,SLOT(HEAP_LIM))
- moveq IMM(0),DTEMP1
- movl DTEMP1,DISP(PSTATE_REG,SLOT(HEAP_MARGIN))
-
- /* continuation must be discarded... */
-
- movl DISP(PSTATE_REG,SLOT(BOS_RET)),PVM0_REG
-
- movl CONST(1),ATEMP1 /* jump to ##exception.heap-overflow proc */
- moveq IMM(1),DTEMP1 /* passing 0 argument */
- jmp IND(ATEMP1)
-
- LBL(fatal_overflow):
-
- movl DISP(PSTATE_REG,SLOT(BOS_RET)),PVM0_REG
-
- movl CONST(2),ATEMP1
- moveq IMM(1),DTEMP1
- jmp IND(ATEMP1)
-
- LBL(allocated):
-
- /* Check to see if we can grow the heap margin */
-
- movl DISP(PSTATE_REG,SLOT(HEAP_LIM)),DTEMP1
- subl DISP(PSTATE_REG,SLOT(HEAP_MARGIN)),DTEMP1
- addl DISP(PSTATE_REG,SLOT(HEAP_MAX_MARGIN)),DTEMP1
- CMPL( DTEMP1,HEAP_REG)
- BCSS( cant_grow)
-
- movl DTEMP1,DISP(PSTATE_REG,SLOT(HEAP_LIM))
- movl DISP(PSTATE_REG,SLOT(HEAP_MAX_MARGIN)),DISP(PSTATE_REG,SLOT(HEAP_MARGIN))
-
- LBL(cant_grow):
- movl PINC(SP),PVM4_REG
- movl PINC(SP),PVM3_REG
- movl PINC(SP),PVM2_REG
- movl PINC(SP),PVM1_REG
- movl PINC(SP),PVM0_REG
- rts
-
- CONSTS(3)
- PRIMITIVE("##gc")
- PRIMITIVE("##exception.heap-overflow")
- PRIMITIVE("##fatal-heap-overflow")
- END
-
- /*---------------------------------------------------------------------------*/
-
- #undef LBL
- #define LBL(x)MAKE_LBL(16,x)
-
- BEGIN("###_kernel.trap_15")
-
- /* closure_alloc */
-
- movl DTEMP1,ATEMP2
-
- GET_TRAP_RETURN(0)
- movl DTEMP1,PDEC(SP)
-
- movl ATEMP2,DTEMP1
- movl DTEMP1,PDEC(SP)
-
- addl IMM(CLOSURE_BLOCK_LENGTH+CACHE_LINE_LENGTH),DTEMP1
- subl DTEMP1,HEAP_REG
- CMPL( DISP(PSTATE_REG,SLOT(HEAP_LIM)),HEAP_REG) /* heap overflow */
- BCCS( ok)
-
- TRAP(heap_alloc2_trap,alloc,2,1)
-
- LBL(ok):
- movl HEAP_REG,DTEMP1
- addl IMM(CACHE_LINE_LENGTH),DTEMP1
- andw IMM(-CACHE_LINE_LENGTH),DTEMP1
- movl DTEMP1,ATEMP1
- movl ATEMP1,DISP(PSTATE_REG,SLOT(CLOSURE_LIM))
- addl IMM(CLOSURE_BLOCK_LENGTH),ATEMP1
- movl ATEMP1,DISP(PSTATE_REG,SLOT(CLOSURE_PTR))
-
- addl PINC(SP),ATEMP1
-
- /* init closure block: */
-
- movl IMM(0x80080000+JSR_OP),DTEMP1
- lea PC_IND(closure_trampoline),ATEMP2
- BRAS( loop_entry)
- LBL(loop):
- subql IMM(CACHE_LINE_LENGTH-8),ATEMP1
- movl ATEMP2,PDEC(ATEMP1)
- movl DTEMP1,PDEC(ATEMP1)
- LBL(loop_entry):
- CMPL( ATEMP1,HEAP_REG)
- BLTS( loop)
-
- movl DISP(PSTATE_REG,SLOT(FLUSH_WRITES)),PDEC(SP)
- jsr DISP(TABLE_REG,TRAP_OFFS(C_TRAP_trap))
-
- movl DISP(PSTATE_REG,SLOT(CLOSURE_PTR)),ATEMP2
-
- rts
-
- LBL(closure_trampoline):
- movl IND(SP),ATEMP1
- movl PDEC(ATEMP1),ATEMP1
- jmp IND(ATEMP1)
-
- CONSTS(0)
- END
-
- /*---------------------------------------------------------------------------*/
-
- #undef LBL
- #define LBL(x)MAKE_LBL(17,x)
-
- BEGIN("###_kernel.trap_16")
-
- /* delay_future */
-
- GET_TRAP_RETURN(0)
- movl DTEMP1,PVM0_REG
-
- /* Allocate special "DELAY" frame. */
-
- moveq IMM(11+4+PH_SIZE*4),DTEMP1
- addw DISP(PVM0_REG,-6),DTEMP1 /* get fs */
- andw IMM(-8),DTEMP1
- subl DTEMP1,HEAP_REG
-
- /* Check need to GC. */
-
- CMPL( DISP(PSTATE_REG,SLOT(HEAP_LIM)),HEAP_REG)
- BCCS( space_allocated)
- LBL(gc_needed):
- movl PVM0_REG,PDEC(SP)
- TRAP(heap_alloc2_trap,alloc,1,1)
- movl PINC(SP),PVM0_REG
-
- LBL(space_allocated):
- addw IMM(PH_SIZE*4),HEAP_REG
-
- moveq IMM(4),DTEMP1
- addw DISP(PVM0_REG,-6),DTEMP1
- asll IMM(8),DTEMP1
- movb IMM(SCM_subtype_VECTOR*8),DTEMP1
- movl DTEMP1,IND(HEAP_REG)
-
- /* Copy the frame. */
-
- lsrl IMM(8),DTEMP1
- lsrl IMM(2),DTEMP1
- subql IMM(2),DTEMP1
-
- moveq IMM(0),PVM1_REG
- movw DISP(PVM0_REG,-4),PVM1_REG /* get link */
- movl INXW(SP,PVM1_REG,0),ATEMP2
-
- lea DISP(HEAP_REG,SLOT(1)),ATEMP1
- movl PVM0_REG,PINC(ATEMP1)
- LBL(copy_loop):
- movl PINC(SP),PINC(ATEMP1)
- DBRA( DTEMP1,copy_loop)
-
- /* Make placeholder. */
-
- lea DISP(HEAP_REG,SCM_type_SUBTYPED),ATEMP1
- clrl PDEC(HEAP_REG)
- movl ATEMP1,PDEC(HEAP_REG)
- movl NULL_REG,PDEC(HEAP_REG)
- lea DISP(HEAP_REG,SCM_type_PLACEHOLDER-4),ATEMP1
- movl ATEMP1,PDEC(HEAP_REG)
-
- /* Return placeholder. */
-
- movl ATEMP1,PVM1_REG
-
- jmp IND(ATEMP2)
-
- CONSTS(0)
- END
-
- /*---------------------------------------------------------------------------*/
-
- #undef LBL
- #define LBL(x)MAKE_LBL(18,x)
-
- BEGIN("###_kernel.trap_17")
-
- /* eager_future */
-
- GET_TRAP_RETURN(0)
- movl DTEMP1,PVM0_REG
-
- /* broken... */
-
- jmp IND(PVM0_REG)
-
- CONSTS(0)
- END
-
- /*---------------------------------------------------------------------------*/
-
- #undef LBL
- #define LBL(x)MAKE_LBL(19,x)
-
- BEGIN("###_kernel.trap_18")
-
- /* steal_conflict */
-
- GET_TRAP_RETURN(0)
- movl DTEMP1,ATEMP2
-
- /* get consistent value for LTQ_HEAD */
-
- movl FALSE_REG,DISP(PSTATE_REG,SLOT(STEAL_LOCKO))
-
- /*
- tstl DISP(PSTATE_REG,SLOT(STEAL_LOCKV))
- BEQS( locked)
-
- addql IMM(8),DISP(PSTATE_REG,SLOT(56))
- */
-
- LBL(lock_steal):
- tstl DISP(PSTATE_REG,SLOT(STEAL_LOCKV))
- BNES( lock_steal)
- LBL(locked):
-
- movl DISP(PSTATE_REG,SLOT(LTQ_HEAD)),ATEMP1
-
- clrl DISP(PSTATE_REG,SLOT(STEAL_LOCKO))
-
- /* Who won the race for the continuation? */
-
- CMPL( ATEMP1,LTQ_TAIL_REG)
- BCSS( thief_won)
-
- /* Continue normally */
-
- jmp IND(ATEMP2)
-
- LBL(thief_won):
-
- movl SP,PINC(LTQ_TAIL_REG)
-
- movl CONST(0),ATEMP1
- addw IMM(16),ATEMP1
- movl ATEMP1,DISP(PSTATE_REG,SLOT(PARENT_RET))
-
- #ifdef debug
- /*****/ pea PC_IND($entry)
- /*****/ movl PINC(SP),DISP(PSTATE_REG,SLOT(56))
- /*****/ movl IMM(0),DISP(PSTATE_REG,SLOT(57))
- /*****/ movl IMM(0),DISP(PSTATE_REG,SLOT(58))
- #endif
-
- movl DISP(PSTATE_REG,SLOT(BOS_RET)),ATEMP1
- jmp IND(ATEMP1)
-
- CONSTS(1)
- PRIMITIVE("###_kernel.task")
- END
-
- /*---------------------------------------------------------------------------*/
-
- #undef LBL
- #define LBL(x)MAKE_LBL(20,x)
-
- BEGIN("###_kernel.trap_19")
-
- BRAS( $entry)
-
- CONSTS(0)
- END
-
- /*---------------------------------------------------------------------------*/
-
- #undef LBL
- #define LBL(x)MAKE_LBL(21,x)
-
- BEGIN("###_kernel.trap_20")
-
- BRAS( $entry)
-
- CONSTS(0)
- END
-
- /*---------------------------------------------------------------------------*/
-
- #undef LBL
- #define LBL(x)MAKE_LBL(22,x)
-
- BEGIN("###_kernel.trap_21")
-
- BRAS( $entry)
-
- CONSTS(0)
- END
-
- /*---------------------------------------------------------------------------*/
-
- #undef LBL
- #define LBL(x)MAKE_LBL(23,x)
-
- BEGIN("###_kernel.trap_22")
-
- /* C_TRAP */
-
- movl REG(a4),PDEC(SP)
- movl REG(a3),PDEC(SP)
- movl REG(a2),PDEC(SP)
- movl REG(a1),PDEC(SP)
- movl REG(a0),PDEC(SP)
- movl DISP(SP,4+SLOT(5)),REG(a0)
- movl REG(d7),PDEC(SP)
- movl REG(d6),PDEC(SP)
- movl REG(d5),PDEC(SP)
- movl REG(d4),PDEC(SP)
- movl REG(d3),PDEC(SP)
- movl REG(d2),PDEC(SP)
- movl REG(d1),PDEC(SP)
- movl REG(d0),PDEC(SP)
-
- movl SP,DISP(PSTATE_REG,SLOT(STACK_PTR))
-
- movl CONST(0),REG(a1) /* restore C's registers */
- #ifndef MIN_C_CONTEXT
- movl DISP(REG(a1),C_D2),REG(d2)
- movl DISP(REG(a1),C_D3),REG(d3)
- movl DISP(REG(a1),C_D4),REG(d4)
- movl DISP(REG(a1),C_D5),REG(d5)
- movl DISP(REG(a1),C_D6),REG(d6)
- movl DISP(REG(a1),C_D7),REG(d7)
- movl DISP(REG(a1),C_A2),REG(a2)
- movl DISP(REG(a1),C_A3),REG(a3)
- movl DISP(REG(a1),C_A4),REG(a4)
- #endif
- movl DISP(REG(a1),C_A5),REG(a5)
- movl DISP(REG(a1),C_A6),REG(a6)
- movl DISP(REG(a1),C_SP),SP
-
- jsr IND(REG(a0)) /* call C procedure */
-
- movl CONST(0),REG(a2)
- movl DISP(REG(a2),C_SP),ATEMP1 /* get TABLE_REG & PSTATE_REG */
- movl DISP(ATEMP1,4),TABLE_REG /* restore Scheme context */
- movl DISP(ATEMP1,8),PSTATE_REG
-
- movl DISP(PSTATE_REG,SLOT(STACK_PTR)),SP
-
- movl PINC(SP),REG(d0)
- movl PINC(SP),REG(d1)
- movl PINC(SP),REG(d2)
- movl PINC(SP),REG(d3)
- movl PINC(SP),REG(d4)
- movl PINC(SP),REG(d5)
- movl PINC(SP),REG(d6)
- movl PINC(SP),REG(d7)
- movl PINC(SP),REG(a0)
- movl PINC(SP),REG(a1)
- movl PINC(SP),REG(a2)
- movl PINC(SP),REG(a3)
- movl PINC(SP),REG(a4)
-
- movl PINC(SP),IND(SP)
-
- rts
-
- CONSTS(1)
- PRIMITIVE("###_kernel")
- END
-
- /*---------------------------------------------------------------------------*/
-
- #undef LBL
- #define LBL(x)MAKE_LBL(24,x)
-
- BEGIN("###_kernel.trap_23")
-
- /* C_CALL */
-
- movl CONST(0),REG(a2)
- movl DISP(REG(a2),C_SP),ATEMP2
-
- movl IMM(SCM_marker),PDEC(ATEMP2)
-
- tstw DTEMP1
- BMIS( passed_1arg)
- BEQS( passed_2args)
-
- subqw IMM(3),DTEMP1
- BMIS( move_remaining_args)
-
- movl PVM3_REG, TEMP1) /* jump to procedure (with >= 3 args) */
-
- LBL(pass_0arg):
- moveq IMM(1),DTEMP1
- jmp IND(ATEMP1) /* jump to procedure (with no arg) */
-
- LBL(pass_1arg):
- movl PINC(SP),PVM1_REG
- moveq IMM(-1),DTEMP1
- jmp IND(ATEMP1) /* jump to procedure (with 1 arg) */
-
- LBL(pass_2args):
- movl PINC(SP),PVM2_REG
- movl PINC(SP),PVM1_REG
- moveq IMM(0),DTEMP1
- jmp IND(ATEMP1) /* jump to procedure (with 2 args) */
-
- CONSTS(0)
- END
-
- /*---------------------------------------------------------------------------*/
-
- #undef LBL
- #define LBL(x)MAKE_LBL(27,x)
-
- BEGIN("###_kernel.wrong-nb-arg")
-
- /* make room for 'procedure' argument */
-
- movw DTEMP1,PVM1_REG
- movl SP,ATEMP2
- subql IMM(4),SP
- BRAS( loop_entry)
- LBL(loop):
- movl PINC(ATEMP2),DISP(ATEMP2,-8)
- LBL(loop_entry):
- DBRA( PVM1_REG,loop)
-
- movl ATEMP1,DISP(ATEMP2,-4) /* put 'procedure' argument */
- addqw IMM(1),DTEMP1
-
- movl CONST(0),ATEMP1 /* apply ##exception.wrong-nb-arg */
- movl CONST(1),ATEMP2
- jmp IND(ATEMP2)
-
- CONSTS(2)
- PRIMITIVE("##exception.wrong-nb-arg")
- PRIMITIVE("###_kernel.apply")
- END
-
- /*---------------------------------------------------------------------------*/
-
- #undef LBL
- #define LBL(x)MAKE_LBL(28,x)
-
- BEGIN("###_kernel.switch-task")
-
- CMPL( DISP(PSTATE_REG,SLOT(LTQ_HEAD)),LTQ_TAIL_REG)
- BNES( there_are_other_tasks)
-
- CMPL( DISP(PSTATE_REG,SLOT(WORKQ_TAIL)),NULL_REG)
- BNES( there_are_other_tasks)
-
- movl FALSE_REG,PVM1_REG /* no other tasks to switch to */
- jmp IND(PVM0_REG)
-
- LBL(there_are_other_tasks):
-
- LOG(EVENT_TASK_SWITCH,log1)
-
- movl PVM0_REG,PDEC(SP)
-
- /* Call ###_kernel.transfer-lazy-tasks-to-heap. */
-
- pea PC_IND(ret1)
- movl CONST(0),ATEMP1
- jmp IND(ATEMP1)
- RETURN(ret1,1,1):
-
- /* Call ###_kernel.transfer-stack-to-heap. */
-
- /* ###_kernel.transfer-lazy-tasks-to-heap has reserved enough */
- /* space, so no GC check required. */
-
- pea PC_IND(ret2)
- movl CONST(1),ATEMP1
- jmp IND(ATEMP1)
- LBL(ret2):
-
- /* Save state of current task. */
-
- movl DISP(PSTATE_REG,SLOT(CURRENT_TASK)),ATEMP1
-
- movl PINC(SP),PVM0_REG
- movl PVM0_REG,DISP(ATEMP1,SLOT(TASK_CONT_RET)+4-SCM_type_SUBTYPED)
- movl PVM2_REG,DISP(ATEMP1,SLOT(TASK_CONT_FRAME)+4-SCM_type_SUBTYPED)
- movl DISP(PSTATE_REG,SLOT(CURRENT_DYN_ENV)),DISP(ATEMP1,SLOT(TASK_CONT_DYN_ENV)+4-SCM_type_SUBTYPED)
- movl IMM(SCM_true),DISP(ATEMP1,SLOT(TASK_VALUE)+4-SCM_type_SUBTYPED)
-
- /* Add task to workq. */
-
- movl ATEMP1,PDEC(HEAP_REG)
-
- #ifdef MAINTAIN_TASK_STATUS
-
- /* Change task's status to READY */
-
- movl HEAP_REG,DISP(ATEMP1,SLOT(TASK_STATUS)+4-SCM_type_SUBTYPED)
-
- #endif
-
- movl FALSE_REG,DISP(PSTATE_REG,SLOT(WORKQ_LOCKO))
- LBL(lock_workq):
- tstl DISP(PSTATE_REG,SLOT(WORKQ_LOCKV))
- BNES( lock_workq)
-
- movl DISP(PSTATE_REG,SLOT(WORKQ_TAIL)),ATEMP1
- CMPL( ATEMP1,NULL_REG)
- BNES( non_empty_queue)
- movl HEAP_REG,DISP(PSTATE_REG,SLOT(WORKQ_HEAD))
- BRAS( fix_tail)
- LBL(non_empty_queue):
- movl HEAP_REG,PDEC(ATEMP1)
-
- LBL(fix_tail):
- movl HEAP_REG,DISP(PSTATE_REG,SLOT(WORKQ_TAIL))
-
- movl NULL_REG,PDEC(HEAP_REG)
-
- clrl DISP(PSTATE_REG,SLOT(WORKQ_LOCKO))
-
- /* Go idle. */
-
- moveq IMM(0),PVM1_REG
- movl CONST(2),ATEMP1
- jmp IND(ATEMP1)
-
- CONSTS(3)
- PRIMITIVE("###_kernel.transfer-lazy-tasks-to-heap")
- PRIMITIVE("###_kernel.transfer-stack-to-heap")
- PRIMITIVE("###_kernel.idle")
- END
-
- /*---------------------------------------------------------------------------*/
-
- #undef LBL
- #define LBL(x)MAKE_LBL(29,x)
-
- BEGIN("###_kernel.idle")
-
- #ifdef MAINTAIN_TASK_STATUS
-
- BEQS( find_work)
-
- movl PVM1_REG,ATEMP1
-
- /* Check if task is really READY */
-
- lea DISP(ATEMP1,SLOT(TASK_LOCKV)+4-SCM_type_SUBTYPED),ATEMP1
- LBL(lock_task1):
- LOCK_ATEMP1(lock1)
- tstl DISP(ATEMP1,SLOT(TASK_LOCKO-TASK_LOCKV))
- BEQS( task_locked1)
- clrl IND(ATEMP1)
- BRAS( lock_task1)
-
- LBL(task_locked1):
- movl DISP(ATEMP1,SLOT(TASK_STATUS-TASK_LOCKV)),DTEMP1
- btst DTEMP1,PAIR_REG
- BNES( task_not_ready1)
-
- movl DTEMP1,ATEMP2 /* remove task from workq */
- movl FALSE_REG,IND(ATEMP2)
-
- /* Change task's status to RUNNING */
-
- movl PSTATE_REG,DISP(ATEMP1,SLOT(TASK_STATUS-TASK_LOCKV))
- clrl IND(ATEMP1)
-
- lea DISP(ATEMP1,-(SLOT(TASK_LOCKV)+4-SCM_type_SUBTYPED)),ATEMP1
-
- #ifdef debug
- /*****/ movl IMM(1),DISP(PSTATE_REG,SLOT(58))
- #endif
-
- BRAW( resume_task)
-
- LBL(task_not_ready1):
- clrl IND(ATEMP1)
-
- #endif
-
- LBL(find_work):
-
- LOG(EVENT_IDLE,log1)
-
- LBL(try_our_workq):
-
- /* Try removing task from our own workq. */
-
- movl FALSE_REG,DISP(PSTATE_REG,SLOT(WORKQ_LOCKO))
- LBL(lock_workq1):
- tstl DISP(PSTATE_REG,SLOT(WORKQ_LOCKV))
- BNES( lock_workq1)
-
- movl DISP(PSTATE_REG,SLOT(WORKQ_HEAD)),ATEMP1
- CMPL( ATEMP1,NULL_REG)
- BEQS( empty_queue1)
- movl PDEC(ATEMP1),ATEMP2
- movl ATEMP2,DISP(PSTATE_REG,SLOT(WORKQ_HEAD))
- CMPL( ATEMP2,NULL_REG)
- BNES( done1)
- movl ATEMP2,DISP(PSTATE_REG,SLOT(WORKQ_TAIL))
- LBL(done1):
-
- clrl DISP(PSTATE_REG,SLOT(WORKQ_LOCKO))
-
- /* Check if task is really READY */
-
- movl DISP(ATEMP1,SLOT(1)),ATEMP1
-
- #ifdef MAINTAIN_TASK_STATUS
-
- CMPL( ATEMP1,FALSE_REG)
- BEQS( try_our_workq)
-
- lea DISP(ATEMP1,SLOT(TASK_LOCKV)+4-SCM_type_SUBTYPED),ATEMP1
- LBL(lock_task2):
- LOCK_ATEMP1(lock2)
- tstl DISP(ATEMP1,SLOT(TASK_LOCKO-TASK_LOCKV))
- BEQS( task_locked2)
- clrl IND(ATEMP1)
- BRAS( lock_task2)
-
- LBL(task_not_ready2):
- clrl IND(ATEMP1)
- BRAS( try_our_workq)
-
- LBL(task_locked2):
- movl DISP(ATEMP1,SLOT(TASK_STATUS-TASK_LOCKV)),DTEMP1
- btst DTEMP1,PAIR_REG
- BNES( task_not_ready2)
-
- movl DTEMP1,ATEMP2 /* remove task from workq */
- movl FALSE_REG,IND(ATEMP2)
-
- /* Change task's status to RUNNING */
-
- movl PSTATE_REG,DISP(ATEMP1,SLOT(TASK_STATUS-TASK_LOCKV))
- clrl IND(ATEMP1)
-
- lea DISP(ATEMP1,-(SLOT(TASK_LOCKV)+4-SCM_type_SUBTYPED)),ATEMP1
-
- #endif
-
- #ifdef debug
- /*****/ movl IMM(2),DISP(PSTATE_REG,SLOT(58))
- #endif
-
- BRAW( resume_task)
-
- LBL(empty_queue1):
- clrl DISP(PSTATE_REG,SLOT(WORKQ_LOCKO))
-
- LBL(our_workq_empty):
-
- movl FALSE_REG,DISP(PSTATE_REG,SLOT(CURRENT_TASK))
- movl FALSE_REG,DISP(PSTATE_REG,SLOT(PARENT_RET))
- movl FALSE_REG,DISP(PSTATE_REG,SLOT(PARENT_FRAME))
- movl FALSE_REG,DISP(PSTATE_REG,SLOT(CURRENT_DYN_ENV))
-
- moveq IMM(INTR_LATENCY_AFTER_STEAL-1),INTR_TIMER_REG
-
- #ifdef debug
- /*****/ pea PC_IND($entry)
- /*****/ movl PINC(SP),DISP(PSTATE_REG,SLOT(56))
- /*****/ movl IMM(0),DISP(PSTATE_REG,SLOT(57))
- /*****/ movl IMM(0),DISP(PSTATE_REG,SLOT(58))
- #endif
-
- /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
- #ifdef MESSAGE_PASSING_STEAL
-
- /* Prevent other processors from trying to steal from us. */
-
- movl LTQ_TAIL_REG,DISP(PSTATE_REG,SLOT(LTQ_TAIL))
-
- #ifdef SYNCHRONOUS_STEAL
-
- LBL(wait_for_request):
- tstl DISP(PSTATE_REG,SLOT(STEAL_LOCKV))
- BEQS( no_steal)
- movl DISP(PSTATE_REG,SLOT(THIEF)),DTEMP1
- BEQS( wait_for_request)
- clrl DISP(PSTATE_REG,SLOT(THIEF))
- clrl DISP(PSTATE_REG,SLOT(STEAL_LOCKV))
- movl DTEMP1,ATEMP1
- clrl DISP(ATEMP1,SLOT(RESPONSE))
- LBL(no_steal):
-
- #endif
- #endif
- /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
-
- LBL(try_to_steal_from_other_workq):
- movl DISP(PSTATE_REG,SLOT(STEAL_SCAN)),PVM2_REG
- lea DISP(PSTATE_REG,SLOT(PS+MAX_NB_PROC)),ATEMP2
- addl PVM2_REG,ATEMP2
-
- LBL(next_processor):
- subql IMM(4),PVM2_REG
- BLEW( scan_done)
-
- LBL(check_workq):
- subql IMM(4),ATEMP2
- LBL(check_same_workq):
- movl IND(ATEMP2),ATEMP1
- CMPL( DISP(ATEMP1,SLOT(WORKQ_HEAD)),NULL_REG)
- BEQW( empty_queue3)
-
- lea DISP(ATEMP1,SLOT(WORKQ_LOCKV)),ATEMP1
- LBL(lock_workq2):
- LOCK_ATEMP1(lock3)
- tstl DISP(ATEMP1,SLOT(WORKQ_LOCKO-WORKQ_LOCKV))
- BEQS( workq_locked)
- clrl IND(ATEMP1)
- BRAS( lock_workq2)
- LBL(workq_locked):
- movl DISP(ATEMP1,SLOT(WORKQ_HEAD-WORKQ_LOCKV)),PVM0_REG
- CMPL( PVM0_REG,NULL_REG)
- BEQW( empty_queue2)
- movl PDEC(PVM0_REG),DTEMP1
- movl DTEMP1,DISP(ATEMP1,SLOT(WORKQ_HEAD-WORKQ_LOCKV))
- CMPL( DTEMP1,NULL_REG)
- BNES( done2)
- movl DTEMP1,DISP(ATEMP1,SLOT(WORKQ_TAIL-WORKQ_LOCKV))
- LBL(done2):
-
- clrl IND(ATEMP1)
-
- /* Check if task is really READY */
-
- movl DISP(PVM0_REG,SLOT(1)),ATEMP1
-
- #ifdef MAINTAIN_TASK_STATUS
-
- CMPL( ATEMP1,FALSE_REG)
- BEQS( check_same_workq)
-
- lea DISP(ATEMP1,SLOT(TASK_LOCKV)+4-SCM_type_SUBTYPED),ATEMP1
- LBL(lock_task3):
- LOCK_ATEMP1(lock4)
- tstl DISP(ATEMP1,SLOT(TASK_LOCKO-TASK_LOCKV))
- BEQS( task_locked3)
- clrl IND(ATEMP1)
- BRAS( lock_task3)
-
- LBL(task_not_ready3):
- clrl IND(ATEMP1)
- BRAS( check_same_workq)
-
- LBL(task_locked3):
- movl DISP(ATEMP1,SLOT(TASK_STATUS-TASK_LOCKV)),DTEMP1
- btst DTEMP1,PAIR_REG
- BNES( task_not_ready3)
-
- movl DTEMP1,ATEMP2 /* remove task from workq */
- movl FALSE_REG,IND(ATEMP2)
-
- /* Change task's status to RUNNING */
-
- movl PSTATE_REG,DISP(ATEMP1,SLOT(TASK_STATUS-TASK_LOCKV))
- clrl IND(ATEMP1)
-
- lea DISP(ATEMP1,-(SLOT(TASK_LOCKV)+4-SCM_type_SUBTYPED)),ATEMP1
-
- #endif
-
- movl PVM2_REG,DISP(PSTATE_REG,SLOT(STEAL_SCAN))
-
- #ifdef debug
- /*****/ movl IMM(3),DISP(PSTATE_REG,SLOT(58))
- #endif
-
- LBL(resume_task):
-
- /* Resume task. */
-
- movl ATEMP1,DISP(PSTATE_REG,SLOT(CURRENT_TASK))
- movl DISP(ATEMP1,SLOT(TASK_CONT_RET)+4-SCM_type_SUBTYPED),DISP(PSTATE_REG,SLOT(PARENT_RET))
- movl DISP(ATEMP1,SLOT(TASK_CONT_FRAME)+4-SCM_type_SUBTYPED),DISP(PSTATE_REG,SLOT(PARENT_FRAME))
- movl DISP(ATEMP1,SLOT(TASK_CONT_DYN_ENV)+4-SCM_type_SUBTYPED),DISP(PSTATE_REG,SLOT(CURRENT_DYN_ENV))
- movl DISP(ATEMP1,SLOT(TASK_VALUE)+4-SCM_type_SUBTYPED),PVM1_REG
-
- #ifdef debug
- /*****/ pea PC_IND($entry)
- /*****/ movl PINC(SP),DISP(PSTATE_REG,SLOT(56))
- /*****/ movl DISP(PSTATE_REG,SLOT(BOS_RET)),DISP(PSTATE_REG,SLOT(57))
- #endif
-
- movl PVM1_REG,PVM0_REG
- movl PVM1_REG,PVM2_REG
- movl PVM1_REG,PVM3_REG
- movl PVM1_REG,PVM4_REG
-
- LOG(EVENT_WORKING,log2)
-
- movl DISP(PSTATE_REG,SLOT(BOS_RET)),ATEMP1
- jmp IND(ATEMP1)
-
- LBL(empty_queue2):
- clrl IND(ATEMP1)
- lea DISP(ATEMP1,-SLOT(WORKQ_LOCKV)),ATEMP1
- LBL(empty_queue3):
-
- /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
- #ifdef MESSAGE_PASSING_STEAL
-
- /* Check if anything to steal. */
-
- movl DISP(ATEMP1,SLOT(LTQ_HEAD)),DTEMP1
- CMPL( DISP(ATEMP1,SLOT(LTQ_TAIL)),DTEMP1)
- BEQW( next_processor)
-
- #ifdef SYNCHRONOUS_STEAL
-
- movl ATEMP1,PVM4_REG
-
- /* Try to become thief. */
-
- movl ATEMP1,DTEMP1
- addl IMM(SLOT(STEAL_LOCKV)),DTEMP1
- READ_AND_SET_DTEMP1
- tstl DTEMP1
- BNEW( next_processor)
-
- movl PVM4_REG,ATEMP1
- movl DISP(ATEMP1,SLOT(LTQ_HEAD)),DTEMP1
- CMPL( DISP(ATEMP1,SLOT(LTQ_TAIL)),DTEMP1)
- BNES( we_are_thief)
-
- clrl DISP(ATEMP1,SLOT(STEAL_LOCKV))
- BRAW( next_processor)
-
- LBL(we_are_thief):
-
- /* Send steal message to victim. */
-
- movl FALSE_REG,DISP(PSTATE_REG,SLOT(RESPONSE))
- movl PSTATE_REG,DISP(ATEMP1,SLOT(THIEF))
- movl IMM(-1),IND(ATEMP1)
-
- LOG(EVENT_STEALING,log3)
-
- /* Wait for response. */
-
- movl PVM2_REG,DISP(PSTATE_REG,SLOT(STEAL_SCAN))
-
- LBL(wait):
- tstl DISP(PSTATE_REG,SLOT(INTR_BARRIER))
- BEQS( ret3)
- clrl DISP(PSTATE_REG,SLOT(INTR_BARRIER))
- lea PC_IND(ret3),PVM0_REG
- movl PVM0_REG,PVM1_REG
- movl PVM0_REG,PVM2_REG
- movl PVM0_REG,PVM3_REG
- movl PVM0_REG,PVM4_REG
- movl CONST(0),ATEMP1 /* Call ##barrier */
- moveq IMM(1),DTEMP1
- jmp IND(ATEMP1)
- RETURN(ret3,0,0):
- movl DISP(PSTATE_REG,SLOT(RESPONSE)),ATEMP1
- CMPL( ATEMP1,FALSE_REG)
- BEQS( wait)
-
- clrl DISP(PSTATE_REG,SLOT(RESPONSE))
-
- #ifdef debug
- /*****/ movl ATEMP1,DISP(PSTATE_REG,SLOT(58))
- #endif
-
- movl ATEMP1,DTEMP1
- BNEW( resume_task)
-
- LOG(EVENT_IDLE,log4)
-
- BRAW( try_to_steal_from_other_workq)
-
- #else
- /* ASYNCHRONOUS_STEAL */
-
- movl FALSE_REG,DISP(ATEMP1,SLOT(WORK_REQUEST))
- movl IMM(-1),IND(ATEMP1)
- BRAW( next_processor)
-
- #endif
-
- /*---------------------------------------------------------------------------*/
- #else
- /* SHARED_MEMORY_STEAL */
-
- /* acquire steal_lock */
-
- movl DISP(ATEMP1,SLOT(STEAL_LOCKO)),DTEMP1
- BNEW( next_processor)
-
- movl ATEMP1,PVM4_REG
-
- /* Try to become thief. */
-
- movl ATEMP1,DTEMP1
- addl IMM(SLOT(STEAL_LOCKV)),DTEMP1
- READ_AND_SET_DTEMP1
- tstl DTEMP1
- BNEW( next_processor)
-
- movl PVM4_REG,ATEMP1
-
- movl DISP(ATEMP1,SLOT(STEAL_LOCKO)),DTEMP1
- BNES( fail)
-
- movl DISP(ATEMP1,SLOT(LTQ_HEAD)),PVM0_REG
- addql IMM(4),PVM0_REG
- movl PVM0_REG,DISP(ATEMP1,SLOT(LTQ_HEAD))
- movl DISP(PVM0_REG,-SLOT(1)),DTEMP1
- BNES( we_are_thief)
- subql IMM(4),PVM0_REG
- movl PVM0_REG,DISP(ATEMP1,SLOT(LTQ_HEAD))
-
- LBL(fail):
- clrl DISP(ATEMP1,SLOT(STEAL_LOCKV))
- BRAW( next_processor)
-
- LBL(we_are_thief):
-
- movl PVM2_REG,DISP(PSTATE_REG,SLOT(STEAL_SCAN))
-
- /* setup parent task */
-
- movl DISP(PSTATE_REG,SLOT(TEMP_TASK)),PVM2_REG
- movl PVM2_REG,DISP(PSTATE_REG,SLOT(CURRENT_TASK))
- movl PVM2_REG,ATEMP2
- movl DISP(ATEMP2,SLOT(TASK_SYNC_PH)+4-SCM_type_SUBTYPED),PVM1_REG
-
- #ifdef MAINTAIN_TASK_STATUS
-
- /* Link placeholder to current task so that it can get resumed when the */
- /* placeholder is touched (and the task is READY). */
-
- movl PVM1_REG,ATEMP2
- movl DISP(ATEMP1,SLOT(CURRENT_TASK)),DISP(ATEMP2,SLOT(PH_TASK)-SCM_type_PLACEHOLDER)
-
- movl PVM2_REG,ATEMP2
- movl PSTATE_REG,DISP(ATEMP2,SLOT(TASK_STATUS)+4-SCM_type_SUBTYPED)
-
- #endif
-
- /* DTEMP1 = lazy task frame pointer */
-
- movl DTEMP1,ATEMP2 /* get task's return address */
- movl IND(ATEMP2),PVM3_REG
-
- movl DISP(ATEMP1,SLOT(PARENT_RET)),DISP(PSTATE_REG,SLOT(PARENT_RET))
- movl DISP(ATEMP1,SLOT(PARENT_FRAME)),DISP(PSTATE_REG,SLOT(PARENT_FRAME))
- movl DISP(ATEMP1,SLOT(CURRENT_DYN_ENV)),DISP(PSTATE_REG,SLOT(CURRENT_DYN_ENV))
-
- movl PVM3_REG,DISP(ATEMP1,SLOT(PARENT_RET))
- subql IMM(8),PVM3_REG /* convert return adr to normal one */
-
- /* Make child's continuation frame. */
-
- movl PVM3_REG,PDEC(HEAP_REG)
- movl PVM2_REG,PDEC(HEAP_REG)
- /* katz/weise continuations would require stolen stack frame to be put on heap
- movl DISP(ATEMP1,SLOT(PARENT_FRAME)),PDEC(HEAP_REG)
- */
- movl FALSE_REG,PDEC(HEAP_REG)
- movl IMM(3*0x400+(SCM_subtype_FRAME*8)),PDEC(HEAP_REG)
- lea DISP(HEAP_REG,SCM_type_SUBTYPED),ATEMP2
-
- movl ATEMP2,DISP(ATEMP1,SLOT(PARENT_FRAME))
-
- /* copy victim's stack */
-
- movl DISP(PVM0_REG,-SLOT(2)),PVM0_REG /* get base of continuation */
-
- movl DTEMP1,ATEMP2
- movl PVM0_REG,DTEMP1
- subl ATEMP2,DTEMP1 /* DTEMP1 = length of stack area to copy */
-
- subl DTEMP1,SP
- movl SP,PVM0_REG
-
- lsrl IMM(2),DTEMP1
- subql IMM(1),DTEMP1
- LBL(loop):
- movl PINC(ATEMP2),PINC(PVM0_REG)
- DBRA( DTEMP1,loop)
-
- /* unlock steal_lock */
-
- clrl DISP(ATEMP1,SLOT(STEAL_LOCKV))
-
- addql IMM(8),DISP(PSTATE_REG,SLOT(COUNT1))
-
- MAKE_TEMP_TASK
-
- #ifdef debug
- /*****/ pea PC_IND($entry)
- /*****/ movl PINC(SP),DISP(PSTATE_REG,SLOT(56))
- /*****/ movl PVM3_REG,DISP(PSTATE_REG,SLOT(57))
- /*****/ movl IMM(0),DISP(PSTATE_REG,SLOT(58))
- #endif
-
- movl PVM3_REG,ATEMP2
-
- /* Resume task. */
-
- movl PVM1_REG,PVM0_REG
- movl PVM1_REG,PVM2_REG
- movl PVM1_REG,PVM3_REG
- movl PVM1_REG,PVM4_REG
-
- LOG(EVENT_WORKING,log5)
-
- jmp IND(ATEMP2)
-
- #endif
- /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
-
- LBL(scan_done):
- movl DISP(PSTATE_REG,SLOT(NB_PROCESSORS)),PVM2_REG
- asrl IMM(1),PVM2_REG
- movl PVM2_REG,DISP(PSTATE_REG,SLOT(STEAL_SCAN))
-
- tstl DISP(PSTATE_REG,SLOT(INTR_BARRIER))
- BEQS( ret4)
- clrl DISP(PSTATE_REG,SLOT(INTR_BARRIER))
- lea PC_IND(ret4),PVM0_REG
- movl PVM0_REG,PVM1_REG
- movl PVM0_REG,PVM2_REG
- movl PVM0_REG,PVM3_REG
- movl PVM0_REG,PVM4_REG
- movl CONST(0),ATEMP1 /* Call ##barrier */
- moveq IMM(1),DTEMP1
- jmp IND(ATEMP1)
- RETURN(ret4,0,0):
-
- BRAW( try_to_steal_from_other_workq)
-
- CONSTS(1)
- PRIMITIVE("##barrier")
- END
-
- /*---------------------------------------------------------------------------*/
-
- #undef LBL
- #define LBL(x)MAKE_LBL(30,x)
-
- BEGIN("###_kernel.determine!")
-
- #ifdef DETERMINE_IS_STRICT
- btst PVM2_REG,PLACEHOLDER_REG
- BNES( touched)
- movl PVM0_REG,PDEC(SP)
- movl PVM1_REG,PDEC(SP)
- TRAP(TOUCH_trap+2,touch,2,1)
- movl PINC(SP),PVM1_REG
- movl PINC(SP),PVM0_REG
- LBL(touched):
- #endif
-
- movl CONST(0),ATEMP1
- jmp IND(ATEMP1)
-
- CONSTS(1)
- PRIMITIVE("###_kernel.non-strict-determine!")
- END
-
- /*---------------------------------------------------------------------------*/
-
- #undef LBL
- #define LBL(x)MAKE_LBL(31,x)
-
- BEGIN("###_kernel.non-strict-determine!")
-
- movl PVM0_REG,PDEC(SP)
-
- LOG(EVENT_DETERMINE,log1)
-
- btst PVM1_REG,PLACEHOLDER_REG
- BNES( already_determined)
-
- movl PVM1_REG,ATEMP2
- lea DISP(ATEMP2,SLOT(PH_QUEUE)-SCM_type_PLACEHOLDER),ATEMP2
-
- LOCK_ATEMP2(lock1)
-
- CMPL( DTEMP1,FALSE_REG)
- BNES( undetermined)
- movl DTEMP1,IND(ATEMP2)
-
- LBL(already_determined):
- PREV_LOG(2,log2)
- movl PINC(SP),PVM0_REG
- movl CONST(0),ATEMP1 /* jump to ##exception.placeholder-already-determined */
- moveq IMM(1),DTEMP1 /* passing 0 argument */
- jmp IND(ATEMP1)
-
- LBL(undetermined):
- movl PVM2_REG,DISP(ATEMP2,SLOT(PH_VALUE-PH_QUEUE))
-
- movl FALSE_REG,IND(ATEMP2)
-
- /* DTEMP1 is list of tasks to restart. */
-
- btst DTEMP1,PAIR_REG
- BNES( tasks_restarted)
-
- movl DTEMP1,PVM4_REG
- LBL(next_task):
- movl DTEMP1,ATEMP2
-
- /* Setup task's return value. */
-
- movl IND(ATEMP2),ATEMP1
- movl PVM2_REG,DISP(ATEMP1,SLOT(TASK_VALUE)+4-SCM_type_SUBTYPED)
-
- #ifdef MAINTAIN_TASK_STATUS
-
- /* Change task's status to READY */
-
- movl ATEMP2,DISP(ATEMP1,SLOT(TASK_STATUS)+4-SCM_type_SUBTYPED)
-
- #endif
-
- movl DISP(ATEMP2,SLOT(-1)),DTEMP1
- btst DTEMP1,PAIR_REG
- BEQS( next_task)
-
- /* Add tasks to workq. */
-
- movl FALSE_REG,DISP(PSTATE_REG,SLOT(WORKQ_LOCKO))
- LBL(lock_workq):
- tstl DISP(PSTATE_REG,SLOT(WORKQ_LOCKV))
- BNES( lock_workq)
-
- movl DISP(PSTATE_REG,SLOT(WORKQ_TAIL)),ATEMP1
- CMPL( ATEMP1,NULL_REG)
- BNES( non_empty_queue)
- movl PVM4_REG,DISP(PSTATE_REG,SLOT(WORKQ_HEAD))
- BRAS( fix_tail)
- LBL(non_empty_queue):
- movl PVM4_REG,PDEC(ATEMP1)
- LBL(fix_tail):
- movl ATEMP2,DISP(PSTATE_REG,SLOT(WORKQ_TAIL))
-
- clrl DISP(PSTATE_REG,SLOT(WORKQ_LOCKO))
-
- LBL(tasks_restarted):
- movl PVM2_REG,PVM1_REG
- movl PVM2_REG,PVM3_REG
- movl PVM2_REG,PVM4_REG
- movl PINC(SP),PVM0_REG
-
- PREV_LOG(2,log3)
-
- movl PVM2_REG,DTEMP1 /* Required for the case of a return from a touch of d0 */
- jmp IND(PVM0_REG)
-
- CONSTS(1)
- PRIMITIVE("##exception.placeholder-already-determined")
- END
-
- /*---------------------------------------------------------------------------*/
-
- #undef LBL
- #define LBL(x)MAKE_LBL(32,x)
-
- BEGIN("###_kernel.determine!-then-idle")
-
- movl PVM0_REG,PDEC(SP)
-
- #ifdef DETERMINE_IS_STRICT
- btst PVM2_REG,PLACEHOLDER_REG
- BNES( touched)
- movl PVM1_REG,PDEC(SP)
- movl PVM3_REG,PDEC(SP)
- TRAP(TOUCH_trap+2,touch,3,1)
- movl PINC(SP),PVM3_REG
- movl PINC(SP),PVM1_REG
- LBL(touched):
- #endif
-
- LOG(EVENT_DETERMINE,log1)
-
- btst PVM1_REG,PLACEHOLDER_REG
- BNES( already_determined)
-
- movl PVM1_REG,ATEMP2
- lea DISP(ATEMP2,SLOT(PH_QUEUE)-SCM_type_PLACEHOLDER),ATEMP2
-
- LOCK_ATEMP2(lock1)
-
- CMPL( DTEMP1,FALSE_REG)
- BNES( undetermined)
- movl DTEMP1,IND(ATEMP2)
-
- LBL(already_determined):
- PREV_LOG(2,log2)
- movl PINC(SP),PVM0_REG
- movl CONST(1),ATEMP1 /* jump to ##exception.placeholder-already-determined */
- moveq IMM(1),DTEMP1 /* passing 0 argument */
- jmp IND(ATEMP1)
-
- LBL(no_task_to_restart):
- movl PVM3_REG,PVM1_REG
- movl CONST(0),ATEMP1
- jmp IND(ATEMP1)
-
- LBL(undetermined):
- movl PINC(SP),PVM0_REG
-
- movl PVM2_REG,DISP(ATEMP2,SLOT(PH_VALUE-PH_QUEUE))
-
- movl FALSE_REG,IND(ATEMP2)
-
- #ifdef MAINTAIN_TASK_STATUS
-
- /* Change task's status to DEAD */
-
- movl DISP(PSTATE_REG,SLOT(CURRENT_TASK)),ATEMP1
- movl FALSE_REG,DISP(ATEMP1,SLOT(TASK_STATUS)+4-SCM_type_SUBTYPED)
-
- #endif
-
- /* DTEMP1 is list of tasks to restart. */
-
- btst DTEMP1,PAIR_REG
- BNES( no_task_to_restart)
-
- movl DTEMP1,ATEMP2
- movl IND(ATEMP2),PVM3_REG
- movl PDEC(ATEMP2),DTEMP1
- btst DTEMP1,PAIR_REG
- BNES( tasks_restarted)
-
- movl DTEMP1,PVM4_REG
- LBL(next_task):
- movl DTEMP1,ATEMP2
-
- /* Setup task's return value. */
-
- movl IND(ATEMP2),ATEMP1
- movl PVM2_REG,DISP(ATEMP1,SLOT(TASK_VALUE)+4-SCM_type_SUBTYPED)
-
- #ifdef MAINTAIN_TASK_STATUS
-
- /* Change task's status to READY */
-
- movl ATEMP2,DISP(ATEMP1,SLOT(TASK_STATUS)+4-SCM_type_SUBTYPED)
-
- #endif
-
- movl DISP(ATEMP2,SLOT(-1)),DTEMP1
- btst DTEMP1,PAIR_REG
- BEQS( next_task)
-
- /* Add tasks to workq. */
-
- movl FALSE_REG,DISP(PSTATE_REG,SLOT(WORKQ_LOCKO))
- LBL(lock_workq):
- tstl DISP(PSTATE_REG,SLOT(WORKQ_LOCKV))
- BNES( lock_workq)
-
- movl DISP(PSTATE_REG,SLOT(WORKQ_TAIL)),ATEMP1
- CMPL( ATEMP1,NULL_REG)
- BNES( non_empty_queue)
- movl PVM4_REG,DISP(PSTATE_REG,SLOT(WORKQ_HEAD))
- BRAS( fix_tail)
- LBL(non_empty_queue):
- movl PVM4_REG,PDEC(ATEMP1)
- LBL(fix_tail):
- movl ATEMP2,DISP(PSTATE_REG,SLOT(WORKQ_TAIL))
-
- clrl DISP(PSTATE_REG,SLOT(WORKQ_LOCKO))
-
- LBL(tasks_restarted):
-
- movl PVM3_REG,ATEMP1
-
- #ifdef MAINTAIN_TASK_STATUS
-
- /* Change task's status to RUNNING */
-
- movl PSTATE_REG,DISP(ATEMP1,SLOT(TASK_STATUS)+4-SCM_type_SUBTYPED)
-
- #endif
-
- /* Resume task. */
-
- movl ATEMP1,DISP(PSTATE_REG,SLOT(CURRENT_TASK))
- movl DISP(ATEMP1,SLOT(TASK_CONT_RET)+4-SCM_type_SUBTYPED),DISP(PSTATE_REG,SLOT(PARENT_RET))
- movl DISP(ATEMP1,SLOT(TASK_CONT_FRAME)+4-SCM_type_SUBTYPED),DISP(PSTATE_REG,SLOT(PARENT_FRAME))
- movl DISP(ATEMP1,SLOT(TASK_CONT_DYN_ENV)+4-SCM_type_SUBTYPED),DISP(PSTATE_REG,SLOT(CURRENT_DYN_ENV))
-
- #ifdef debug
- /*****/ pea PC_IND($entry)
- /*****/ movl PINC(SP),DISP(PSTATE_REG,SLOT(56))
- /*****/ movl DISP(PSTATE_REG,SLOT(BOS_RET)),DISP(PSTATE_REG,SLOT(57))
- /*****/ movl IMM(0),DISP(PSTATE_REG,SLOT(58))
- #endif
-
- movl PVM2_REG,PVM1_REG
- movl PVM1_REG,PVM0_REG
- movl PVM1_REG,PVM3_REG
- movl PVM1_REG,PVM4_REG
-
- LOG(EVENT_WORKING,log3)
-
- movl DISP(PSTATE_REG,SLOT(BOS_RET)),ATEMP1
- jmp IND(ATEMP1)
-
- CONSTS(2)
- PRIMITIVE("###_kernel.idle")
- PRIMITIVE("##exception.placeholder-already-determined")
- END
-
- /*---------------------------------------------------------------------------*/
-
- #undef LBL
- #define LBL(x)MAKE_LBL(33,x)
-
- BEGIN("###_kernel.touch")
-
- movl PVM0_REG,PDEC(SP)
- movl ATEMP2,PVM4_REG
-
- /* Check if the placeholder was generated by a DELAY. */
-
- tstl DISP(ATEMP2,SLOT(PH_DELAY)-SCM_type_PLACEHOLDER)
- BEQS( not_delay_ph2)
-
- lea DISP(ATEMP2,SLOT(PH_QUEUE)-SCM_type_PLACEHOLDER),ATEMP2
-
- LOCK_ATEMP2(lock1)
-
- movl DISP(ATEMP2,SLOT(PH_DELAY)-SLOT(PH_QUEUE)),PVM1_REG
- BEQS( not_delay_ph1)
-
- clrl DISP(ATEMP2,SLOT(PH_DELAY)-SLOT(PH_QUEUE))
- movl DTEMP1,IND(ATEMP2)
-
- movl PVM4_REG,PDEC(SP)
-
- /* Restore delayed computation. */
-
- subql IMM(SCM_type_SUBTYPED),PVM1_REG
- movl PVM1_REG,ATEMP1
-
- movl PINC(ATEMP1),DTEMP1
- lsrl IMM(8),DTEMP1
- subql IMM(4),DTEMP1
- subl DTEMP1,SP
- lsrl IMM(2),DTEMP1
-
- movl PINC(ATEMP1),PVM0_REG
- subql IMM(1),DTEMP1
- movl SP,ATEMP2
- LBL(copy):
- movl PINC(ATEMP1),PINC(ATEMP2)
- DBRA( DTEMP1,copy)
-
- lea PC_IND(ret1),ATEMP1
-
- moveq IMM(0),PVM1_REG
- movw DISP(PVM0_REG,-4),PVM1_REG /* get link */
- movl ATEMP1,INXW(SP,PVM1_REG,0)
-
- PREV_LOG(2,log1)
-
- movl PVM2_REG,PVM1_REG
- jmp IND(PVM0_REG)
- RETURN(ret1,2,1):
-
- movl PVM1_REG,PVM2_REG
- movl PINC(SP),PVM1_REG
- movl PINC(SP),PVM0_REG
-
- movl CONST(3),ATEMP1 /* jump to ###_kernel.determine! */
- jmp IND(ATEMP1)
-
- LBL(not_delay_ph1):
- movl DTEMP1,IND(ATEMP2)
-
- LBL(not_delay_ph2):
-
- /* Call ###_kernel.transfer-lazy-tasks-to-heap. */
-
- pea PC_IND(ret2)
- movl CONST(0),ATEMP1
- jmp IND(ATEMP1)
- RETURN(ret2,1,1):
-
- /* Call ###_kernel.transfer-stack-to-heap. */
-
- /* ###_kernel.transfer-lazy-tasks-to-heap has reserved enough */
- /* space, so no GC check required. */
-
- pea PC_IND(ret3)
- movl CONST(1),ATEMP1
- jmp IND(ATEMP1)
- LBL(ret3):
-
- /* Save state of current task. */
-
- movl DISP(PSTATE_REG,SLOT(CURRENT_TASK)),ATEMP1
-
- movl PINC(SP),PVM0_REG
- movl PVM0_REG,DISP(ATEMP1,SLOT(TASK_CONT_RET)+4-SCM_type_SUBTYPED)
- movl PVM2_REG,DISP(ATEMP1,SLOT(TASK_CONT_FRAME)+4-SCM_type_SUBTYPED)
- movl DISP(PSTATE_REG,SLOT(CURRENT_DYN_ENV)),DISP(ATEMP1,SLOT(TASK_CONT_DYN_ENV)+4-SCM_type_SUBTYPED)
- movl FALSE_REG,DISP(ATEMP1,SLOT(TASK_VALUE)+4-SCM_type_SUBTYPED)
-
- movl ATEMP1,PDEC(HEAP_REG)
- movl HEAP_REG,PVM3_REG
-
- /* Final check for determinedness. */
-
- btst PVM4_REG,PLACEHOLDER_REG
- BNES( already_determined)
-
- movl PVM4_REG,ATEMP2
- lea DISP(ATEMP2,SLOT(PH_QUEUE)-SCM_type_PLACEHOLDER),ATEMP2
-
- LOCK_ATEMP2(lock2)
-
- CMPL( DTEMP1,FALSE_REG)
- BNES( undetermined)
-
- movl DTEMP1,IND(ATEMP2)
- movl DISP(ATEMP2,SLOT(PH_VALUE-PH_QUEUE)),PVM4_REG
-
- LBL(already_determined):
- addql IMM(4),HEAP_REG
-
- /* Resume task. */
-
- movl DISP(PSTATE_REG,SLOT(CURRENT_TASK)),ATEMP2
- movl DISP(ATEMP2,SLOT(TASK_CONT_RET)+4-SCM_type_SUBTYPED),DISP(PSTATE_REG,SLOT(PARENT_RET))
- movl DISP(ATEMP2,SLOT(TASK_CONT_FRAME)+4-SCM_type_SUBTYPED),DISP(PSTATE_REG,SLOT(PARENT_FRAME))
- movl DISP(ATEMP2,SLOT(TASK_CONT_DYN_ENV)+4-SCM_type_SUBTYPED),DISP(PSTATE_REG,SLOT(CURRENT_DYN_ENV))
-
- #ifdef debug
- /*****/ pea PC_IND($entry)
- /*****/ movl PINC(SP),DISP(PSTATE_REG,SLOT(56))
- /*****/ movl DISP(PSTATE_REG,SLOT(BOS_RET)),DISP(PSTATE_REG,SLOT(57))
- /*****/ movl IMM(0),DISP(PSTATE_REG,SLOT(58))
- #endif
-
- movl PVM4_REG,PVM0_REG
- movl PVM4_REG,PVM1_REG
- movl PVM4_REG,PVM2_REG
- movl PVM4_REG,PVM3_REG
-
- PREV_LOG(2,log2)
-
- movl DISP(PSTATE_REG,SLOT(BOS_RET)),ATEMP1
- jmp IND(ATEMP1)
-
- LBL(undetermined):
- movl DTEMP1,PDEC(HEAP_REG)
- movl PVM3_REG,IND(ATEMP2)
-
- addql IMM(8),DISP(PSTATE_REG,SLOT(COUNT2))
-
- #ifdef MAINTAIN_TASK_STATUS
-
- /* Change task's status to WAITING */
-
- movl DISP(PSTATE_REG,SLOT(CURRENT_TASK)),ATEMP1
- movl NULL_REG,DISP(ATEMP1,SLOT(TASK_STATUS)+4-SCM_type_SUBTYPED)
-
- /* Resume placeholder's task if possible (i.e. if it is READY) */
-
- movl DISP(ATEMP2,SLOT(PH_TASK-PH_QUEUE)),PVM1_REG
- movl CONST(2),ATEMP1
- jmp IND(ATEMP1)
-
- #else
-
- moveq IMM(0),PVM1_REG
- movl CONST(2),ATEMP1
- jmp IND(ATEMP1)
-
- #endif
-
- CONSTS(4)
- PRIMITIVE("###_kernel.transfer-lazy-tasks-to-heap")
- PRIMITIVE("###_kernel.transfer-stack-to-heap")
- PRIMITIVE("###_kernel.idle")
- PRIMITIVE("###_kernel.determine!")
- END
-
- /*---------------------------------------------------------------------------*/
-
- #undef LBL
- #define LBL(x)MAKE_LBL(34,x)
-
- BEGIN("###_kernel.transfer-lazy-task-chunk-to-heap")
-
- /* On entry: */
- /* top of stack = exit address */
- /* PVM2_REG = processor to respond to or task list */
- /* PVM3_REG = stack base */
- /* ATEMP1 = LTQ_HEAD */
-
- /* On exit: */
- /* PVM2_REG = new task list */
- /* PVM4_REG preserved */
- /* PVM0_REG, PVM1_REG, PVM3_REG, DTEMP1, ATEMP1, ATEMP2 modified */
-
- /* It is assumed that: */
- /* - there is at least one lazy task on the lazy task queue */
- /* - no GC will be required (there is enough free space in the heap) */
-
- #ifndef MESSAGE_PASSING_STEAL
- movl ATEMP1,PVM1_REG
- #endif
-
- addql IMM(4),ATEMP1 /* adjust LTQ_HEAD as though taking one task */
-
- lea DISP(LTQ_TAIL_REG,-SLOT(MIN_VICTIM_TASKS)),PVM0_REG
-
- CMPL( ATEMP1,PVM0_REG)
- BLSS( found_split_point2)
-
- movl DISP(PVM0_REG,-SLOT(1)),DTEMP1
-
- movl PVM3_REG,ATEMP2
- lea DISP(ATEMP2,-SLOT(MAX_TASK_FRAME_CHUNK_SIZE)),ATEMP2
-
- CMPL( DTEMP1,ATEMP2)
- BLSS( found_split_point1)
-
- LBL(loop1):
- CMPL( PINC(ATEMP1),ATEMP2)
- BLSS( loop1)
-
- subql IMM(4),ATEMP1
- BRAS( found_split_point2)
-
- LBL(found_split_point1):
- movl PVM0_REG,ATEMP1
- LBL(found_split_point2):
-
- #ifndef MESSAGE_PASSING_STEAL
- movl PVM1_REG,ATEMP2
- LBL(loop2):
- addql IMM(4),ATEMP2
- clrl DISP(ATEMP2,-SLOT(2))
- CMPL( ATEMP2,ATEMP1)
- BNES( loop2)
- #endif
-
- movl CONST(0),ATEMP2
- jmp IND(ATEMP2)
-
- CONSTS(1)
- PRIMITIVE("###_kernel.transfer-lazy-task-to-heap")
- END
-
- /*---------------------------------------------------------------------------*/
-
- #undef LBL
- #define LBL(x)MAKE_LBL(35,x)
-
- BEGIN("###_kernel.transfer-lazy-task-to-heap")
-
- /* On entry: */
- /* top of stack = exit address */
- /* PVM2_REG = processor to respond to or task list */
- /* PVM3_REG = stack base */
- /* ATEMP1 = LTQ split point */
-
- /* On exit: */
- /* PVM2_REG = new task list */
- /* PVM4_REG preserved */
- /* PVM0_REG, PVM1_REG, PVM3_REG, DTEMP1, ATEMP1, ATEMP2 modified */
-
- /* It is assumed that: */
- /* - there is at least one lazy task on the lazy task queue */
- /* - no GC will be required (there is enough free space in the heap) */
-
- movl ATEMP1,DISP(PSTATE_REG,SLOT(LTQ_HEAD))
- movl DISP(ATEMP1,-SLOT(1)),ATEMP2
- movl IND(ATEMP2),DTEMP1
-
- /* DTEMP1 = task's return adr, ATEMP2 = task boundary */
-
- /* Now, we must replace the child's return address with the 'bottom of stack'*/
- /* return address. Because we don't really know where the return address */
- /* is (but we do know its value) we must scan the child's stack until we */
- /* have found the address. */
-
- movl ATEMP2,ATEMP1
- LBL(loop1):
- CMPL( PDEC(ATEMP1),DTEMP1)
- BNES( loop1)
-
- movl DISP(PSTATE_REG,SLOT(BOS_RET)),PVM0_REG
- movl PVM0_REG,IND(ATEMP1)
-
- /* Similarly, replace 'bottom of stack' return address by correct one */
-
- movl PVM3_REG,ATEMP1
- LBL(loop2):
- CMPL( PDEC(ATEMP1),PVM0_REG)
- BNES( loop2)
-
- movl DISP(PSTATE_REG,SLOT(PARENT_RET)),IND(ATEMP1)
-
- /* Next, we must find the dynamic environment of the parent. */
-
- movl DISP(PSTATE_REG,SLOT(CURRENT_DYN_ENV)),PDEC(SP) /*guard*/
- movl DISP(PSTATE_REG,SLOT(DEQ_TAIL)),PVM0_REG
- movl SP,PDEC(PVM0_REG)
-
- movl DISP(PSTATE_REG,SLOT(DEQ_HEAD)),PVM0_REG
- LBL(loop3):
- CMPL( PDEC(PVM0_REG),ATEMP2)
- BCSS( loop3)
-
- addql IMM(4),PVM0_REG
- movl PVM0_REG,DISP(PSTATE_REG,SLOT(DEQ_HEAD))
-
- /* Setup parent task. */
-
- movl DISP(PSTATE_REG,SLOT(TEMP_TASK)),ATEMP1
- movl PDEC(PVM0_REG),PVM0_REG
- movl IND(PVM0_REG),DISP(ATEMP1,SLOT(TASK_CONT_DYN_ENV)+4-SCM_type_SUBTYPED)
- subql IMM(8),DTEMP1 /* convert return adr to normal one */
- movl DTEMP1,DISP(ATEMP1,SLOT(TASK_CONT_RET)+4-SCM_type_SUBTYPED)
-
- #ifdef MAINTAIN_TASK_STATUS
-
- /* Link placeholder to current task so that it can get resumed when the */
- /* placeholder is touched (and the task is READY). */
-
- movl DISP(ATEMP1,SLOT(TASK_SYNC_PH)+4-SCM_type_SUBTYPED),PVM0_REG
- movl DISP(PSTATE_REG,SLOT(CURRENT_TASK)),DISP(PVM0_REG,SLOT(PH_TASK)-SCM_type_PLACEHOLDER)
-
- #endif
-
- addql IMM(4),SP
-
- /* Allocate a single frame object for task's continuation */
-
- /* Compute size of frame object */
-
- subl ATEMP2,PVM3_REG
- addql IMM(4),PVM3_REG
-
- /* Allocate frame object. */
-
- movl PVM3_REG,PVM1_REG
- addw IMM(11),PVM1_REG
- andw IMM(-8),PVM1_REG
- subl PVM1_REG,HEAP_REG
- asll IMM(8),PVM3_REG
- movb IMM(SCM_subtype_FRAME*8),PVM3_REG
- movl PVM3_REG,IND(HEAP_REG)
-
- clrl DISP(HEAP_REG,SLOT(1))
- lea DISP(HEAP_REG,SCM_type_SUBTYPED),PVM0_REG
- movl PVM0_REG,DISP(ATEMP1,SLOT(TASK_CONT_FRAME)+4-SCM_type_SUBTYPED)
-
- /* Make child's continuation frame. */
-
- movl DTEMP1,PDEC(HEAP_REG)
- movl ATEMP1,PDEC(HEAP_REG)
- movl PVM0_REG,PDEC(HEAP_REG)
- movl IMM(3*0x400+(SCM_subtype_FRAME*8)),PDEC(HEAP_REG)
-
- movl PVM0_REG,DTEMP1
-
- /* Check were parent task should go. */
-
- movl PVM2_REG,PVM1_REG
- BEQS( transfer_to_workq)
-
- /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
- #ifdef MESSAGE_PASSING_STEAL
- #ifdef SYNCHRONOUS_STEAL
-
- andw IMM(7),PVM2_REG
- BNES( transfer_to_task_list)
-
- LBL(transfer_to_thief):
-
- /* Transfer task to thief processor. */
-
- movl PVM1_REG,PVM0_REG
-
- #ifdef MAINTAIN_TASK_STATUS
-
- /* Change task's status to RUNNING */
-
- movl PVM0_REG,DISP(ATEMP1,SLOT(TASK_STATUS)+4-SCM_type_SUBTYPED)
-
- #endif
-
- movl ATEMP1,DISP(PVM0_REG,SLOT(RESPONSE))
-
- BRAS( copy_stack)
-
- LBL(transfer_to_task_list):
-
- #endif
- #endif
- /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
-
- /* Add parent task to head of task list. */
-
- movl ATEMP1,PDEC(HEAP_REG)
-
- #ifdef MAINTAIN_TASK_STATUS
-
- /* Change task's status to READY */
-
- movl HEAP_REG,DISP(ATEMP1,SLOT(TASK_STATUS)+4-SCM_type_SUBTYPED)
-
- #endif
-
- movl HEAP_REG,PVM2_REG
- movl PVM1_REG,PDEC(HEAP_REG)
-
- BRAS( copy_stack)
-
- LBL(transfer_to_workq):
-
- /* Add parent task to workq. */
-
- movl ATEMP1,PDEC(HEAP_REG)
-
- #ifdef MAINTAIN_TASK_STATUS
-
- /* Change task's status to READY */
-
- movl HEAP_REG,DISP(ATEMP1,SLOT(TASK_STATUS)+4-SCM_type_SUBTYPED)
-
- #endif
-
- movl FALSE_REG,DISP(PSTATE_REG,SLOT(WORKQ_LOCKO))
- LBL(lock_workq):
- tstl DISP(PSTATE_REG,SLOT(WORKQ_LOCKV))
- BNES( lock_workq)
-
- movl DISP(PSTATE_REG,SLOT(WORKQ_TAIL)),ATEMP1
- CMPL( ATEMP1,NULL_REG)
- BNES( non_empty_queue)
- movl HEAP_REG,DISP(PSTATE_REG,SLOT(WORKQ_HEAD))
- BRAS( fix_tail)
- LBL(non_empty_queue):
- movl HEAP_REG,PDEC(ATEMP1)
- LBL(fix_tail):
- movl HEAP_REG,DISP(PSTATE_REG,SLOT(WORKQ_TAIL))
-
- movl NULL_REG,PDEC(HEAP_REG)
-
- clrl DISP(PSTATE_REG,SLOT(WORKQ_LOCKO))
-
- LBL(copy_stack):
-
- /* Copy stack to frame object. */
-
- /* PVM3_REG=frame_header, ATEMP2=start_of_stack, DTEMP1=frame_object */
-
- lsrl IMM(8),PVM3_REG
- lsrl IMM(2),PVM3_REG
- subql IMM(2),PVM3_REG
-
- movl DTEMP1,ATEMP1
- addql IMM(SLOT(2)-SCM_type_SUBTYPED),ATEMP1
- LBL(copy_loop):
- movl PINC(ATEMP2),PINC(ATEMP1)
- DBRA( PVM3_REG,copy_loop)
-
- movl DTEMP1,ATEMP1
- movl DISP(PSTATE_REG,SLOT(PARENT_FRAME)),DISP(ATEMP1,SLOT(1)-SCM_type_SUBTYPED)
-
- /* Setup new parent continuation. */
-
- lea DISP(ATEMP1,-SLOT(4)),ATEMP1
- movl ATEMP1,DISP(PSTATE_REG,SLOT(PARENT_FRAME))
- movl CONST(0),ATEMP1
- addw IMM(16),ATEMP1
- movl ATEMP1,DISP(PSTATE_REG,SLOT(PARENT_RET))
-
- #ifdef debug
- /*****/ pea PC_IND($entry)
- /*****/ movl PINC(SP),DISP(PSTATE_REG,SLOT(56))
- /*****/ movl IND(SP),DISP(PSTATE_REG,SLOT(57))
- /*****/ movl IMM(0),DISP(PSTATE_REG,SLOT(58))
- #endif
-
- /* Return. */
-
- addql IMM(8),DISP(PSTATE_REG,SLOT(COUNT1))
-
- MAKE_TEMP_TASK
-
- rts
-
- CONSTS(1)
- PRIMITIVE("###_kernel.task")
- END
-
- /*---------------------------------------------------------------------------*/
-
- #undef LBL
- #define LBL(x)MAKE_LBL(36,x)
-
- BEGIN("###_kernel.task")
-
- /* This is the code that is run every time the child's continuation is */
- /* returned from. */
-
- RETURN(child_ret,2,1):
-
- /* First, check if this is the first return from the child. */
-
- movl IND(SP),ATEMP2 /* ATEMP2 = parent task */
- movl PVM1_REG,PDEC(SP)
- movl ATEMP2,DTEMP1
- addl IMM(SLOT(TASK_SYNC_PH)+4-SCM_type_SUBTYPED),DTEMP1
- READ_AND_CLEAR_DTEMP1
- btst DTEMP1,PLACEHOLDER_REG
- BNES( not_first_ret)
-
- /* If it is the first return, determine the synchronization placeholder */
- /* and propagate the legitimacy. */
-
- movl DTEMP1,PDEC(SP)
-
- #ifdef LEGITIMACY
-
- movl DISP(ATEMP2,SLOT(TASK_LEGIT)+4-SCM_type_SUBTYPED),PVM1_REG
-
- /* Legitimacy placeholders can be determined with placeholders. */
- /* So, it is wise to chase the placeholder before doing the determine. */
-
- movl DISP(PSTATE_REG,SLOT(CURRENT_TASK)),ATEMP2
- movl DISP(ATEMP2,SLOT(TASK_LEGIT)+4-SCM_type_SUBTYPED),PVM2_REG
- LBL(next):
- btst PVM2_REG,PLACEHOLDER_REG
- BNES( end_of_chase)
- movl PVM2_REG,ATEMP1
- movl DISP(ATEMP1,SLOT(PH_VALUE)-SCM_type_PLACEHOLDER),PVM2_REG
- CMPL( ATEMP1,PVM2_REG)
- BNES( next)
-
- LBL(end_of_chase):
- lea PC_IND(ret),PVM0_REG
- movl CONST(0),ATEMP1
- jmp IND(ATEMP1)
- RETURN(ret,4,1):
-
- #endif
-
- /* Determine value placeholder */
-
- movl PINC(SP),PVM1_REG
- movl PINC(SP),PVM2_REG
- movl PINC(SP),PVM3_REG
- movl PINC(SP),PVM0_REG
- movl CONST(1),ATEMP1
- jmp IND(ATEMP1)
-
- LBL(not_first_ret):
- movl PINC(SP),PVM1_REG
- addql IMM(4),SP
- rts
-
- CONSTS(2)
- PRIMITIVE("###_kernel.non-strict-determine!")
- PRIMITIVE("###_kernel.determine!-then-idle")
- END
-
- /*---------------------------------------------------------------------------*/
-
- #undef LBL
- #define LBL(x)MAKE_LBL(37,x)
-
- BEGIN("###_kernel.transfer-lazy-tasks-to-heap")
-
- /* On entry: */
- /* top of stack = exit address */
-
- /* On exit: */
- /* PVM2_REG = task list */
- /* PVM4_REG preserved */
- /* PVM0_REG, PVM1_REG, PVM3_REG, DTEMP1, ATEMP2 modified */
-
- /* We must make sure that there is enough free space for all the frames (so */
- /* that we can avoid to check for GC on every one). If each frame is copied */
- /* independently, the heap space required could be as much as 4 times the */
- /* space used on the stack plus a certain amount for every lazy task. */
-
- #ifndef MESSAGE_PASSING_STEAL
- movl FALSE_REG,DISP(PSTATE_REG,SLOT(STEAL_LOCKO))
- LBL(lock_steal1):
- tstl DISP(PSTATE_REG,SLOT(STEAL_LOCKV))
- BNES( lock_steal1)
- movl DISP(PSTATE_REG,SLOT(LTQ_HEAD)),ATEMP1
- movl DISP(ATEMP1,-SLOT(1)),DTEMP1
- clrl DISP(PSTATE_REG,SLOT(STEAL_LOCKO))
- #else
- movl DISP(PSTATE_REG,SLOT(LTQ_HEAD)),ATEMP1
- movl DISP(ATEMP1,-SLOT(1)),DTEMP1
- #endif
- subl SP,DTEMP1
- asll IMM(2),DTEMP1
-
- movl LTQ_TAIL_REG,PVM1_REG
- subl ATEMP1,PVM1_REG
- muluw IMM((TASK_SIZE+1)+(PH_SIZE*2)+PAIR_SIZE+6),PVM1_REG
-
- addl PVM1_REG,DTEMP1
- andw IMM(-8),DTEMP1
-
- CMPL( DTEMP1,HEAP_REG)
- subl DTEMP1,HEAP_REG /* allocate space for frames and check heap */
- BCSS( do_gc)
- CMPL( DISP(PSTATE_REG,SLOT(HEAP_LIM)),HEAP_REG) /* overflow */
- BCCS( enough_space)
- LBL(do_gc):
-
- moveq IMM(0),PVM1_REG
- movl DTEMP1,PDEC(SP)
- TRAP(heap_alloc2_trap,alloc,2,1)
- movl PINC(SP),DTEMP1
-
- CMPL( DTEMP1,HEAP_REG)
- subl DTEMP1,HEAP_REG /* allocate space for frames and check heap */
- BCSS( stack_overflow)
- CMPL( DISP(PSTATE_REG,SLOT(HEAP_LIM)),HEAP_REG) /* overflow */
- BCCS( enough_space)
- LBL(stack_overflow):
- addl DTEMP1,HEAP_REG
-
- /* continuation must be discarded... */
-
- movl DISP(PSTATE_REG,SLOT(BOS_RET)),PVM0_REG
-
- movl CONST(2),ATEMP1 /* jump to ##exception.stack-overflow proc */
- moveq IMM(1),DTEMP1 /* passing 0 argument */
- jmp IND(ATEMP1)
-
- LBL(enough_space):
- addl DTEMP1,HEAP_REG
-
- /* At this point, we know that there is enough free space on the heap to */
- /* copy the frames. */
-
- /* Transfer a first task. */
-
- movl NULL_REG,PVM2_REG /* specify task list up to now */
-
- #ifndef MESSAGE_PASSING_STEAL
- movl FALSE_REG,DISP(PSTATE_REG,SLOT(STEAL_LOCKO))
- LBL(lock_steal2):
- tstl DISP(PSTATE_REG,SLOT(STEAL_LOCKV))
- BNES( lock_steal2)
-
- /* fix PARENT_RET if it is a lazy future return point */
-
- movl DISP(PSTATE_REG,SLOT(PARENT_RET)),PVM0_REG
- tstw DISP(PVM0_REG,-6)
- BPLS( fixed)
-
- movl DISP(PSTATE_REG,SLOT(LTQ_HEAD)),ATEMP1
- movl DISP(ATEMP1,-SLOT(1)),ATEMP1
- LBL(loop1):
- CMPL( PDEC(ATEMP1),PVM0_REG)
- BNES( loop1)
- movl DISP(PSTATE_REG,SLOT(BOS_RET)),IND(ATEMP1)
-
- movl CONST(3),PVM0_REG
- addw IMM(16),PVM0_REG
- movl PVM0_REG,DISP(PSTATE_REG,SLOT(PARENT_RET))
-
- LBL(fixed):
-
- #endif
-
- movl DISP(PSTATE_REG,SLOT(LTQ_HEAD)),ATEMP1
- movl DISP(ATEMP1,-SLOT(1)),PVM3_REG
- CMPL( LTQ_TAIL_REG,ATEMP1)
- BEQS( tasks_transferred)
-
- addql IMM(4),ATEMP1 /* adjust LTQ_HEAD by one task */
-
- pea PC_IND(ret)
- movl CONST(0),ATEMP2
- jmp IND(ATEMP2)
-
- LBL(ret):
- movl PVM2_REG,DISP(PSTATE_REG,SLOT(TEMP1)) /* save first task */
-
- /* Transfer the rest. */
-
- LBL(loop2):
- movl DISP(PSTATE_REG,SLOT(LTQ_HEAD)),ATEMP1
- movl DISP(ATEMP1,-SLOT(1)),PVM3_REG
- CMPL( LTQ_TAIL_REG,ATEMP1)
- BEQS( done)
-
- pea PC_IND(loop2)
- movl CONST(1),ATEMP2
- jmp IND(ATEMP2)
-
- LBL(done):
-
- /* Put the tasks on the workq. */
-
- movl FALSE_REG,DISP(PSTATE_REG,SLOT(WORKQ_LOCKO))
- LBL(lock_workq):
- tstl DISP(PSTATE_REG,SLOT(WORKQ_LOCKV))
- BNES( lock_workq)
-
- movl DISP(PSTATE_REG,SLOT(WORKQ_TAIL)),ATEMP1
- CMPL( ATEMP1,NULL_REG)
- BNES( non_empty_queue)
- movl PVM2_REG,DISP(PSTATE_REG,SLOT(WORKQ_HEAD))
- BRAS( fix_tail)
- LBL(non_empty_queue):
- movl PVM2_REG,PDEC(ATEMP1)
- LBL(fix_tail):
- movl DISP(PSTATE_REG,SLOT(TEMP1)),DISP(PSTATE_REG,SLOT(WORKQ_TAIL))
-
- clrl DISP(PSTATE_REG,SLOT(WORKQ_LOCKO))
-
- LBL(tasks_transferred):
-
- #ifndef MESSAGE_PASSING_STEAL
- clrl DISP(PSTATE_REG,SLOT(STEAL_LOCKO))
- #endif
-
- rts
-
- CONSTS(4)
- PRIMITIVE("###_kernel.transfer-lazy-task-to-heap")
- PRIMITIVE("###_kernel.transfer-lazy-task-chunk-to-heap")
- PRIMITIVE("##exception.stack-overflow")
- PRIMITIVE("###_kernel.task")
- END
-
- /*---------------------------------------------------------------------------*/
-
- #undef LBL
- #define LBL(x)MAKE_LBL(38,x)
-
- BEGIN("###_kernel.transfer-stack-to-heap")
-
- /* On entry: */
- /* top of stack = exit address */
- /* next on stack = continuation's return address */
-
- /* On exit: */
- /* top of stack = continuation's return address */
- /* PVM2_REG = continuation's first frame */
- /* PVM4_REG preserved */
- /* PVM0_REG, PVM1_REG, PVM3_REG, DTEMP1, ATEMP1, ATEMP2 modified */
-
- /* It is assumed that: */
- /* - no GC will be required (there is enough free space in the heap) */
- /* - there are no tasks on the stack */
-
- movl DISP(PSTATE_REG,SLOT(BOS_RET)),PVM3_REG
- lea DISP(SP,SLOT(1)),ATEMP2
- movl PINC(ATEMP2),PVM0_REG
- CMPL( PVM0_REG,PVM3_REG)
- BNES( non_empty_stack)
-
- movl DISP(PSTATE_REG,SLOT(PARENT_RET)),DISP(SP,SLOT(1))
- movl DISP(PSTATE_REG,SLOT(PARENT_FRAME)),PVM2_REG
-
- #ifdef debug
- /*****/ pea PC_IND($entry)
- /*****/ movl PINC(SP),DISP(PSTATE_REG,SLOT(56))
- /*****/ movl IND(SP),DISP(PSTATE_REG,SLOT(57))
- /*****/ movl IMM(0),DISP(PSTATE_REG,SLOT(58))
- #endif
-
- rts
-
- LBL(non_empty_stack):
-
- /* Chunk frames together. */
-
- lea DISP(ATEMP2,SLOT(MAX_FRAME_CHUNK_SIZE)),ATEMP1
-
- moveq IMM(0),PVM1_REG
- movw DISP(PVM0_REG,-6),PVM1_REG /* get fs */
- BGTS( normal_ret_a1)
- #ifdef debug
- /*****/ BEQS( dyn_env_ret_a1)
- /*****/ jmp 3
- /*****/LBL(dyn_env_ret_a1):
- #endif
- movw IMM(SLOT(DYN_ENV_FS)),PVM1_REG
- LBL(normal_ret_a1):
- addl ATEMP2,PVM1_REG
- BRAS( try_to_add_next_frame1)
-
- LBL(not_bottom_of_stack1):
- movl PVM1_REG,ATEMP2
- moveq IMM(0),PVM1_REG
- movw DISP(PVM0_REG,-6),PVM1_REG /* get fs */
- BGTS( normal_ret_b1)
- #ifdef debug
- /*****/ BEQS( dyn_env_ret_b1)
- /*****/ jmp 5
- /*****/LBL(dyn_env_ret_b1):
- #endif
- movw IMM(SLOT(DYN_ENV_FS)),PVM1_REG
- LBL(normal_ret_b1):
- addl ATEMP2,PVM1_REG
- CMPL( ATEMP1,PVM1_REG)
- BHIS( chunk_found1)
- LBL(try_to_add_next_frame1):
- addw DISP(PVM0_REG,-4),ATEMP2 /* add link */
- movl IND(ATEMP2),PVM0_REG
- CMPL( PVM0_REG,PVM3_REG) /* bottom of stack? */
- BNES( not_bottom_of_stack1)
- movl DISP(PSTATE_REG,SLOT(PARENT_RET)),IND(ATEMP2)
- movl PVM1_REG,ATEMP2
-
- LBL(chunk_found1): /* ATEMP2 = chunk's upper limit */
-
- /* Now, compute size of frame object to hold chunk. */
-
- movl ATEMP2,PVM1_REG
- lea DISP(ATEMP1,-SLOT(MAX_FRAME_CHUNK_SIZE)),ATEMP2
- subl ATEMP2,PVM1_REG
- addql IMM(4),PVM1_REG
-
- /* Allocate frame object. */
-
- movl PVM1_REG,DTEMP1
- addw IMM(11),DTEMP1
- andw IMM(-8),DTEMP1
- subl DTEMP1,HEAP_REG
- asll IMM(8),PVM1_REG
- movb IMM(SCM_subtype_FRAME*8),PVM1_REG
- movl PVM1_REG,IND(HEAP_REG)
-
- /* Remember where first frame object is. */
-
- movl HEAP_REG,PVM2_REG
- addql IMM(SCM_type_SUBTYPED),PVM2_REG
-
- LBL(copy_stack):
-
- /* Copy stack to frame object. */
-
- /* PVM1_REG=frame_header, ATEMP2=start_of_chunk, HEAP_REG=frame_object */
-
- lsrl IMM(8),PVM1_REG
- lsrl IMM(2),PVM1_REG
- subql IMM(2),PVM1_REG
-
- lea DISP(HEAP_REG,SLOT(2)),ATEMP1
- LBL(copy_loop):
- movl PINC(ATEMP2),PINC(ATEMP1)
- DBRA( PVM1_REG,copy_loop)
-
- CMPL( PVM0_REG,PVM3_REG) /* bottom of stack? */
- BNES( next_chunks)
-
- movl DISP(PSTATE_REG,SLOT(PARENT_FRAME)),DISP(HEAP_REG,SLOT(1))
- rts
-
- LBL(next_chunks):
-
- /* Process next chunk(s). */
-
- lea DISP(ATEMP2,SLOT(MAX_FRAME_CHUNK_SIZE)),ATEMP1
-
- moveq IMM(0),PVM1_REG
- movw DISP(PVM0_REG,-6),PVM1_REG /* get fs */
- BGTS( normal_ret_a2)
- #ifdef debug
- /*****/ BEQS( dyn_env_ret_a2)
- /*****/ jmp 7
- /*****/LBL(dyn_env_ret_a2):
- #endif
- movw IMM(SLOT(DYN_ENV_FS)),PVM1_REG
- LBL(normal_ret_a2):
- addl ATEMP2,PVM1_REG
- BRAS( try_to_add_next_frame2)
-
- LBL(not_bottom_of_stack2):
- movl PVM1_REG,ATEMP2
- moveq IMM(0),PVM1_REG
- movw DISP(PVM0_REG,-6),PVM1_REG /* get fs */
- BGTS( normal_ret_b2)
- #ifdef debug
- /*****/ BEQS( dyn_env_ret_b2)
- /*****/ jmp 9
- /*****/LBL(dyn_env_ret_b2):
- #endif
- movw IMM(SLOT(DYN_ENV_FS)),PVM1_REG
- LBL(normal_ret_b2):
- addl ATEMP2,PVM1_REG
- CMPL( ATEMP1,PVM1_REG)
- BHIS( chunk_found2)
- LBL(try_to_add_next_frame2):
- addw DISP(PVM0_REG,-4),ATEMP2 /* add link */
- movl IND(ATEMP2),PVM0_REG
- CMPL( PVM0_REG,PVM3_REG) /* bottom of stack? */
- BNES( not_bottom_of_stack2)
- movl DISP(PSTATE_REG,SLOT(PARENT_RET)),IND(ATEMP2)
- movl PVM1_REG,ATEMP2
-
- LBL(chunk_found2): /* ATEMP2 = chunk's upper limit */
-
- /* Now, compute size of frame object to hold chunk. */
-
- movl ATEMP2,PVM1_REG
- lea DISP(ATEMP1,-SLOT(MAX_FRAME_CHUNK_SIZE)),ATEMP2
- subl ATEMP2,PVM1_REG
- addql IMM(4),PVM1_REG
-
- /* Remember previous frame object */
-
- movl HEAP_REG,ATEMP1
-
- /* Allocate frame object. */
-
- movl PVM1_REG,DTEMP1
- addw IMM(11),DTEMP1
- andw IMM(-8),DTEMP1
- subl DTEMP1,HEAP_REG
- asll IMM(8),PVM1_REG
- movb IMM(SCM_subtype_FRAME*8),PVM1_REG
- movl PVM1_REG,IND(HEAP_REG)
-
- /* Link with previous frame object */
-
- addql IMM(SCM_type_SUBTYPED),HEAP_REG
- movl HEAP_REG,DISP(ATEMP1,SLOT(1))
- subql IMM(SCM_type_SUBTYPED),HEAP_REG
-
- BRAW( copy_stack)
-
- CONSTS(0)
- END
-
- /*---------------------------------------------------------------------------*/
-
- #undef LBL
- #define LBL(x)MAKE_LBL(39,x)
-
- BEGIN("###_kernel.flush-stack")
-
- movl PVM0_REG,PDEC(SP)
-
- /* Call ###_kernel.transfer-lazy-tasks-to-heap. */
-
- pea PC_IND(ret1)
- movl CONST(0),ATEMP1
- jmp IND(ATEMP1)
- RETURN(ret1,1,1):
-
- /* Call ###_kernel.transfer-stack-to-heap. */
-
- /* ###_kernel.transfer-lazy-tasks-to-heap has reserved enough */
- /* space, so no GC check required. */
-
- pea PC_IND(ret2)
- movl CONST(1),ATEMP1
- jmp IND(ATEMP1)
- LBL(ret2):
-
- /* Setup 'hidden' parent continuation. */
-
- movl IND(SP),DISP(PSTATE_REG,SLOT(PARENT_RET))
- movl PVM2_REG,DISP(PSTATE_REG,SLOT(PARENT_FRAME))
-
- #ifdef debug
- /*****/ pea PC_IND($entry)
- /*****/ movl PINC(SP),DISP(PSTATE_REG,SLOT(56))
- /*****/ movl DISP(PSTATE_REG,SLOT(BOS_RET)),DISP(PSTATE_REG,SLOT(57))
- /*****/ movl IMM(0),DISP(PSTATE_REG,SLOT(58))
- #endif
-
- /* Return to parent */
-
- moveq IMM(0),PVM1_REG
- movl PVM1_REG,PVM2_REG
- movl PVM1_REG,PVM3_REG
-
- movl DISP(PSTATE_REG,SLOT(BOS_RET)),PVM0_REG
- jmp IND(PVM0_REG)
-
- CONSTS(2)
- PRIMITIVE("###_kernel.transfer-lazy-tasks-to-heap")
- PRIMITIVE("###_kernel.transfer-stack-to-heap")
- END
-
- /*---------------------------------------------------------------------------*/
-
- #undef LBL
- #define LBL(x)MAKE_LBL(40,x)
-
- BEGIN("##call-with-current-continuation")
-
- BMIS( passed_1arg)
-
- WRONG_NB_ARGS(wrong_nb_arg1_trap,1,$entry)
-
- LBL(passed_1arg):
-
- movl PVM1_REG,PVM4_REG
- movl PVM0_REG,PDEC(SP)
-
- /* Call ###_kernel.transfer-lazy-tasks-to-heap. */
-
- pea PC_IND(ret1)
- movl CONST(0),ATEMP1
- jmp IND(ATEMP1)
- RETURN(ret1,1,1):
-
- /* Call ###_kernel.transfer-stack-to-heap. */
-
- /* ###_kernel.transfer-lazy-tasks-to-heap has reserved enough */
- /* space, so no GC check required. */
-
- pea PC_IND(ret2)
- movl CONST(1),ATEMP1
- jmp IND(ATEMP1)
- LBL(ret2):
-
- /* Setup 'hidden' parent continuation. */
-
- movl PINC(SP),PVM0_REG
- movl PVM0_REG,DISP(PSTATE_REG,SLOT(PARENT_RET))
- movl PVM2_REG,DISP(PSTATE_REG,SLOT(PARENT_FRAME))
-
- #ifdef debug
- /*****/ pea PC_IND($entry)
- /*****/ movl PINC(SP),DISP(PSTATE_REG,SLOT(56))
- /*****/ movl DISP(PSTATE_REG,SLOT(BOS_RET)),DISP(PSTATE_REG,SLOT(57))
- /*****/ movl IMM(0),DISP(PSTATE_REG,SLOT(58))
- #endif
-
- /* Return to parent */
-
- movl DISP(PSTATE_REG,SLOT(BOS_RET)),PDEC(SP)
-
- moveq IMM(0),PVM1_REG
- movl PVM1_REG,PVM3_REG
-
- /* Allocate closure for 'first-class' continuation. */
-
- movl DISP(PSTATE_REG,SLOT(CLOSURE_PTR)),ATEMP2
- moveq IMM(32),DTEMP1
- subl DTEMP1,ATEMP2
- CMPL( DISP(PSTATE_REG,SLOT(CLOSURE_LIM)),ATEMP2)
- BCCS( closure_allocated)
-
- moveq IMM(0),PVM1_REG
- TRAP(closure_alloc_trap,closure_alloc,1,1)
-
- LBL(closure_allocated):
- movl ATEMP2,DISP(PSTATE_REG,SLOT(CLOSURE_PTR))
-
- /* Init closure. */
-
- movw IMM(0x8010),PINC(ATEMP2)
- movl ATEMP2,PVM1_REG
- addql IMM(2),ATEMP2
- lea PC_IND(closure),ATEMP1
- movl ATEMP1,PINC(ATEMP2)
- movl PVM0_REG,PINC(ATEMP2)
- movl PVM2_REG,PINC(ATEMP2)
- movl DISP(PSTATE_REG,SLOT(CURRENT_DYN_ENV)),IND(ATEMP2)
-
- movl PINC(SP),PVM0_REG
-
- movl PVM4_REG,ATEMP1
- moveq IMM(-1),DTEMP1
- jmp IND(ATEMP1)
-
- /* This code is executed when the 'first-class' continuation is restored. */
-
- SUBPROC(closure):
- movl PINC(SP),CLOSURE_REG
- subql IMM(6),CLOSURE_REG
- tstw DTEMP1
-
- BMIS( closure_was_passed_1arg)
-
- WRONG_NB_ARGS(wrong_nb_arg1_closed_trap,1,closure)
-
- LBL(closure_was_passed_1arg):
-
- /* Call ###_kernel.transfer-lazy-tasks-to-heap. */
-
- CMPL( DISP(PSTATE_REG,SLOT(LTQ_HEAD)),LTQ_TAIL_REG)
- BEQS( tasks_transferred)
-
- movl PVM0_REG,PDEC(SP)
- movl PVM1_REG,PDEC(SP)
- pea PC_IND(ret3)
- movl CONST(0),ATEMP1
- jmp IND(ATEMP1)
- RETURN(ret3,2,1):
- movl PINC(SP),PVM1_REG
- movl PINC(SP),PVM0_REG
- moveq IMM(0),PVM3_REG
-
- LBL(tasks_transferred):
-
- /* Setup 'hidden' parent continuation. */
-
- movl CLOSURE_REG,ATEMP1
- movl DISP(ATEMP1,6),DISP(PSTATE_REG,SLOT(PARENT_RET))
- movl DISP(ATEMP1,10),DISP(PSTATE_REG,SLOT(PARENT_FRAME))
- movl DISP(ATEMP1,14),DISP(PSTATE_REG,SLOT(CURRENT_DYN_ENV))
-
- #ifdef debug
- /*****/ pea PC_IND($entry)
- /*****/ movl PINC(SP),DISP(PSTATE_REG,SLOT(56))
- /*****/ movl DISP(PSTATE_REG,SLOT(BOS_RET)),DISP(PSTATE_REG,SLOT(57))
- /*****/ movl IMM(0),DISP(PSTATE_REG,SLOT(58))
- #endif
-
- /* Restore parent continuation. */
-
- movl DISP(PSTATE_REG,SLOT(BOS_RET)),ATEMP1
- jmp IND(ATEMP1)
-
- CONSTS(2)
- PRIMITIVE("###_kernel.transfer-lazy-tasks-to-heap")
- PRIMITIVE("###_kernel.transfer-stack-to-heap")
- END
-
- /*---------------------------------------------------------------------------*/
-
- #undef LBL
- #define LBL(x)MAKE_LBL(41,x)
-
- BEGIN("##apply")
-
- BEQS( passed_2args)
-
- WRONG_NB_ARGS(wrong_nb_arg1_trap,2,$entry)
-
- LBL(passed_2args):
- movl PVM1_REG,ATEMP1
- movl PVM2_REG,PVM3_REG
-
- moveq IMM(0),DTEMP1
- BRAS( loop_entry)
-
- /* copy values from list to the stack */
-
- LBL(loop):
- movl PVM3_REG,ATEMP2
- movl IND(ATEMP2),PDEC(SP) /* push car to the stack */
- movl PDEC(ATEMP2),PVM3_REG /* get cdr */
-
- addqw IMM(1),DTEMP1
- CMPW( IMM(MAX_NB_ARGS),DTEMP1)
- BGTS( max_args_reached)
-
- LBL(loop_entry):
- btst PVM3_REG,PAIR_REG /* pair? */
- BEQS( loop)
-
- moveq IMM(0),INTR_TIMER_REG /* check interrupts as soon as possible */
-
- tstw DTEMP1 /* how many arguments to pass? */
- BEQS( pass_0arg)
- subqw IMM(2),DTEMP1
- BMIS( pass_1arg)
- BEQS( pass_2args)
-
- movl PINC(SP),PVM3_REG
- movl PINC(SP),PVM2_REG
- movl PINC(SP),PVM1_REG
- addqw IMM(3),DTEMP1
- jmp IND(ATEMP1) /* jump to procedure (with >= 3 args) */
-
- LBL(pass_0arg):
- moveq IMM(1),DTEMP1
- jmp IND(ATEMP1) /* jump to procedure (with no arg) */
-
- LBL(pass_1arg):
- movl PINC(SP),PVM1_REG
- moveq IMM(-1),DTEMP1
- jmp IND(ATEMP1) /* jump to procedure (with 1 arg) */
-
- LBL(pass_2args):
- movl PINC(SP),PVM2_REG
- movl PINC(SP),PVM1_REG
- moveq IMM(0),DTEMP1
- jmp IND(ATEMP1) /* jump to procedure (with 2 args) */
-
- LBL(max_args_reached):
- aslw IMM(2),DTEMP1
- addw DTEMP1,SP /* restore original SP */
-
- movl CONST(0),ATEMP1 /* jump to ##exception.apply-arg-limit */
- moveq IMM(0),DTEMP1 /* passing 2 arguments */
- jmp IND(ATEMP1)
-
- CONSTS(1)
- PRIMITIVE("##exception.apply-arg-limit")
- END
-
- /*---------------------------------------------------------------------------*/
-
- #undef LBL
- #define LBL(x)MAKE_LBL(42,x)
-
- BEGIN("##global-var")
-
- BMIS( passed_1arg)
-
- WRONG_NB_ARGS(wrong_nb_arg1_trap,1,$entry)
-
- LBL(passed_1arg):
- movl PVM1_REG,ATEMP2
- movl DISP(ATEMP2,SLOT(SYMBOL_GLOBAL)+4-SCM_type_SUBTYPED),PVM1_REG
-
- CMPL( PVM1_REG,FALSE_REG)
- BEQS( alloc_glob)
-
- jmp IND(PVM0_REG)
-
- LBL(alloc_glob):
- movl DISP(TABLE_REG,GLOB_OFFS(GLOBAL_VAR_COUNT)),ATEMP1
- movl ATEMP1,PVM1_REG
- addql IMM(8),ATEMP1
- CMPL( IMM(MAX_NB_GLOBALS*8),ATEMP1)
- BLES( ok)
-
- movl FALSE_REG,PVM1_REG
- jmp IND(PVM0_REG)
-
- LBL(ok):
- movl ATEMP1,DISP(TABLE_REG,GLOB_OFFS(GLOBAL_VAR_COUNT))
- movl PVM1_REG,DISP(ATEMP2,SLOT(SYMBOL_GLOBAL)+4-SCM_type_SUBTYPED)
-
- jmp IND(PVM0_REG)
-
- CONSTS(0)
- END
-
- /*---------------------------------------------------------------------------*/
-
- #undef LBL
- #define LBL(x)MAKE_LBL(43,x)
-
- BEGIN("##global-var-ref")
-
- BMIS( passed_1arg)
-
- WRONG_NB_ARGS(wrong_nb_arg1_trap,1,$entry)
-
- LBL(passed_1arg):
- movl PVM1_REG,ATEMP1
- addl TABLE_REG,ATEMP1
- subl IMM((NB_TRAPS*8-0x8000)+(MAX_NB_GLOBALS*10)),ATEMP1
-
- movl IND(ATEMP1),PVM1_REG
- jmp IND(PVM0_REG)
-
- CONSTS(0)
- END
-
- /*---------------------------------------------------------------------------*/
-
- #undef LBL
- #define LBL(x)MAKE_LBL(44,x)
-
- BEGIN("##global-var-set!")
-
- BEQS( passed_2args)
-
- WRONG_NB_ARGS(wrong_nb_arg1_trap,2,$entry)
-
- LBL(passed_2args):
- movl PVM1_REG,DTEMP1
- asrl IMM(2),DTEMP1
- addl TABLE_REG,DTEMP1
- subl IMM(NB_TRAPS*8-0x8000),DTEMP1
- subl IMM(MAX_NB_GLOBALS*2),DTEMP1
-
- movl PVM1_REG,ATEMP1
- addl TABLE_REG,ATEMP1
- subl IMM(NB_TRAPS*8-0x8000),ATEMP1
- subl IMM(MAX_NB_GLOBALS*10),ATEMP1
-
- movl PVM2_REG,PINC(ATEMP1)
- movl DTEMP1,IND(ATEMP1)
-
- jmp IND(PVM0_REG)
-
- CONSTS(0)
- END
-
- /*---------------------------------------------------------------------------*/
-
- #undef LBL
- #define LBL(x)MAKE_LBL(45,x)
-
- BEGIN("##make-vector")
-
- BEQS( passed_2args)
-
- WRONG_NB_ARGS(wrong_nb_arg1_trap,2,$entry)
-
- LBL(passed_2args):
- movl PVM1_REG,DTEMP1
- asrl IMM(1),DTEMP1
- addl IMM(11),DTEMP1
- andw IMM(-8),DTEMP1 /* DTEMP1 = total bytes needed for vector */
-
- CMPL( DTEMP1,HEAP_REG)
- subl DTEMP1,HEAP_REG /* allocate space for vector and check heap overflow */
- BCSS( gc)
- CMPL( DISP(PSTATE_REG,SLOT(HEAP_LIM)),HEAP_REG)
- BCCS( ok)
- LBL(gc):
- movl PVM0_REG,PDEC(SP)
- TRAP(heap_alloc2_trap,alloc1,1,1)
- movl PINC(SP),PVM0_REG
-
- LBL(ok):
- movl PVM1_REG,DTEMP1
- asll IMM(7),DTEMP1
- movb IMM(SCM_subtype_VECTOR*8),DTEMP1
- movl DTEMP1,IND(HEAP_REG)
-
- /* init vector: */
-
- movl PVM1_REG,DTEMP1
- asrl IMM(1),DTEMP1
- lea DISP(HEAP_REG,4),ATEMP1
- LBL(loop):
- movl PVM2_REG,PINC(ATEMP1)
- subql IMM(4),DTEMP1
- BGTS( loop)
-
- movl HEAP_REG,PVM1_REG
- addql IMM(SCM_type_SUBTYPED),PVM1_REG
-
- jmp IND(PVM0_REG) /* return to caller */
-
- CONSTS(0)
- END
-
- /*---------------------------------------------------------------------------*/
-
- #undef LBL
- #define LBL(x)MAKE_LBL(46,x)
-
- BEGIN("##make-string")
-
- BEQS( passed_2args)
-
- WRONG_NB_ARGS(wrong_nb_arg1_trap,2,$entry)
-
- LBL(passed_2args):
- movl PVM1_REG,DTEMP1
- asrl IMM(3),DTEMP1
- addl IMM(11),DTEMP1
- andw IMM(-8),DTEMP1 /* DTEMP1 = total bytes needed for string */
-
- CMPL( DTEMP1,HEAP_REG)
- subl DTEMP1,HEAP_REG /* allocate space for string and check heap overflow */
- BCSS( gc)
- CMPL( DISP(PSTATE_REG,SLOT(HEAP_LIM)),HEAP_REG)
- BCCS( ok)
- LBL(gc):
- movl PVM0_REG,PDEC(SP)
- TRAP(heap_alloc2_trap,alloc1,1,1)
- movl PINC(SP),PVM0_REG
-
- LBL(ok):
- movl PVM1_REG,DTEMP1
- asll IMM(5),DTEMP1
- movb IMM(SCM_subtype_STRING*8),DTEMP1
- movl DTEMP1,IND(HEAP_REG)
-
- /* init string: */
-
- movl PVM2_REG,DTEMP1
- asrw IMM(3),DTEMP1
- andw IMM(0xff),DTEMP1
- movw DTEMP1,ATEMP2
- aslw IMM(8),DTEMP1
- addw ATEMP2,DTEMP1
- movw DTEMP1,ATEMP2
- swap DTEMP1
- movw ATEMP2,DTEMP1
- movl DTEMP1,ATEMP2 /* ATEMP2 = initial value of chars */
-
- movl PVM1_REG,DTEMP1
- asrl IMM(3),DTEMP1
- lea DISP(HEAP_REG,4),ATEMP1
- LBL(loop):
- movl ATEMP2,PINC(ATEMP1)
- subql IMM(4),DTEMP1
- BGTS( loop)
-
- movl HEAP_REG,PVM1_REG
- addql IMM(SCM_type_SUBTYPED),PVM1_REG
-
- jmp IND(PVM0_REG) /* return to caller */
-
- CONSTS(0)
- END
-
- /*---------------------------------------------------------------------------*/
-
- #undef LBL
- #define LBL(x)MAKE_LBL(47,x)
-
- BEGIN("##make-vector16")
-
- BEQS( passed_2args)
-
- WRONG_NB_ARGS(wrong_nb_arg1_trap,2,$entry)
-
- LBL(passed_2args):
- movl PVM1_REG,DTEMP1
- asrl IMM(2),DTEMP1
- addl IMM(11),DTEMP1
- andw IMM(-8),DTEMP1 /* DTEMP1 = total bytes needed for vector */
-
- CMPL( DTEMP1,HEAP_REG)
- subl DTEMP1,HEAP_REG /* allocate space for vector and check heap overflow */
- BCSS( gc)
- CMPL( DISP(PSTATE_REG,SLOT(HEAP_LIM)),HEAP_REG)
- BCCS( ok)
- LBL(gc):
- movl PVM0_REG,PDEC(SP)
- TRAP(heap_alloc2_trap,alloc1,1,1)
- movl PINC(SP),PVM0_REG
-
- LBL(ok):
- movl PVM1_REG,DTEMP1
- asll IMM(6),DTEMP1
- movb IMM(SCM_subtype_STRING*8),DTEMP1
- movl DTEMP1,IND(HEAP_REG)
-
- /* init vector: */
-
- movl PVM2_REG,DTEMP1
- asrl IMM(3),DTEMP1
- movw DTEMP1,ATEMP2
- swap DTEMP1
- movw ATEMP2,DTEMP1
- movl DTEMP1,ATEMP2 /* ATEMP2 = initial value of words */
-
- movl PVM1_REG,DTEMP1
- asrl IMM(2),DTEMP1
- lea DISP(HEAP_REG,4),ATEMP1
- LBL(loop):
- movl ATEMP2,PINC(ATEMP1)
- subql IMM(4),DTEMP1
- BGTS( loop)
-
- movl HEAP_REG,PVM1_REG
- addql IMM(SCM_type_SUBTYPED),PVM1_REG
-
- jmp IND(PVM0_REG) /* return to caller */
-
- CONSTS(0)
- END
-
- /*---------------------------------------------------------------------------*/
-
- #undef LBL
- #define LBL(x)MAKE_LBL(48,x)
-
- BEGIN("##dynamic-env-bind")
-
- BEQS( passed_2args)
-
- WRONG_NB_ARGS(wrong_nb_arg1_trap,2,$entry)
-
- LBL(passed_2args):
-
- /* save current dynamic environment */
-
- movl PVM0_REG,PDEC(SP)
- movl DISP(PSTATE_REG,SLOT(CURRENT_DYN_ENV)),PDEC(SP)
-
- /* set new dynamic environment */
-
- movl PVM1_REG,DISP(PSTATE_REG,SLOT(CURRENT_DYN_ENV))
-
- /* push dynamic environment marker (only if none other pushed for this future) */
-
- movl DISP(PSTATE_REG,SLOT(DEQ_TAIL)),ATEMP2
- movl IND(ATEMP2),PVM0_REG
- movl DISP(LTQ_TAIL_REG,-SLOT(1)),ATEMP1
- CMPL( ATEMP1,PVM0_REG)
- BCSS( pushed)
- movl SP,PDEC(ATEMP2)
- movl ATEMP2,DISP(PSTATE_REG,SLOT(DEQ_TAIL))
- LBL(pushed):
-
- lea PC_IND(ret),PVM0_REG
- movl PVM2_REG,ATEMP1
- moveq IMM(1),DTEMP1
- jmp IND(ATEMP1)
-
- RETURN(ret,DYN_ENV_FS-DYN_ENV_FS,1-DYN_ENV_FS):
- /* A fs of 0 is a special return point marker. Here it indicates a return */
- /* point for dyn env frames. The frame size is really 2 (DYN_ENV_FS). */
-
- /* pop dynamic environment marker */
-
- movl DISP(PSTATE_REG,SLOT(DEQ_TAIL)),ATEMP2
- movl PINC(ATEMP2),ATEMP1
- CMPL( ATEMP1,SP)
- BNES( popped)
- movl ATEMP2,DISP(PSTATE_REG,SLOT(DEQ_TAIL))
- LBL(popped):
-
- /* restore current dynamic environment */
-
- movl PINC(SP),DISP(PSTATE_REG,SLOT(CURRENT_DYN_ENV))
- rts
-
- CONSTS(0)
- END
-
- /*---------------------------------------------------------------------------*/
-
- #undef LBL
- #define LBL(x)MAKE_LBL(49,x)
-
- BEGIN("##dynamic-env-ref")
-
- CMPW( IMM(1),DTEMP1)
- BEQS( passed_0arg)
-
- WRONG_NB_ARGS(wrong_nb_arg1_trap,0,$entry)
-
- LBL(passed_0arg):
- movl DISP(PSTATE_REG,SLOT(CURRENT_DYN_ENV)),PVM1_REG
- jmp IND(PVM0_REG)
-
- CONSTS(0)
- END
-
- /*---------------------------------------------------------------------------*/
-
- #undef LBL
- #define LBL(x)MAKE_LBL(50,x)
-
- BEGIN("##atomic-car")
-
- BMIS( passed_1arg)
-
- WRONG_NB_ARGS(wrong_nb_arg1_trap,1,$entry)
-
- LBL(passed_1arg):
- andw IMM(-8),PVM1_REG
- movl PVM1_REG,ATEMP2
-
- moveq IMM(-1),DTEMP1
- LBL(loop):
- movl DISP(ATEMP2,4),PVM1_REG
- CMPL( PVM1_REG,DTEMP1)
- BEQS( loop)
-
- jmp IND(PVM0_REG)
-
- CONSTS(0)
- END
-
- /*---------------------------------------------------------------------------*/
-
- #undef LBL
- #define LBL(x)MAKE_LBL(51,x)
-
- BEGIN("##atomic-set-car!")
-
- BEQS( passed_2args)
-
- WRONG_NB_ARGS(wrong_nb_arg1_trap,2,$entry)
-
- LBL(passed_2args):
- movl PVM0_REG,PVM4_REG
- movl PVM1_REG,DTEMP1
- andw IMM(-8),DTEMP1
- addql IMM(4),DTEMP1
- movl DTEMP1,ATEMP2
-
- LOCK_ATEMP2(lock)
-
- movl PVM2_REG,IND(ATEMP2)
- movl DTEMP1,PVM1_REG
- movl PVM4_REG,PVM0_REG
- jmp IND(PVM0_REG)
-
- CONSTS(0)
- END
-
- /*---------------------------------------------------------------------------*/
-
- #undef LBL
- #define LBL(x)MAKE_LBL(52,x)
-
- BEGIN("##atomic-cdr")
-
- BMIS( passed_1arg)
-
- WRONG_NB_ARGS(wrong_nb_arg1_trap,1,$entry)
-
- LBL(passed_1arg):
- andw IMM(-8),PVM1_REG
- movl PVM1_REG,ATEMP2
-
- moveq IMM(-1),DTEMP1
- LBL(loop):
- movl IND(ATEMP2),PVM1_REG
- CMPL( PVM1_REG,DTEMP1)
- BEQS( loop)
-
- jmp IND(PVM0_REG)
-
- CONSTS(0)
- END
-
- /*---------------------------------------------------------------------------*/
-
- #undef LBL
- #define LBL(x)MAKE_LBL(53,x)
-
- BEGIN("##atomic-set-cdr!")
-
- BEQS( passed_2args)
-
- WRONG_NB_ARGS(wrong_nb_arg1_trap,2,$entry)
-
- LBL(passed_2args):
- movl PVM0_REG,PVM4_REG
- movl PVM1_REG,DTEMP1
- andw IMM(-8),DTEMP1
- movl DTEMP1,ATEMP2
-
- LOCK_ATEMP2(lock)
-
- movl PVM2_REG,IND(ATEMP2)
- movl DTEMP1,PVM1_REG
- movl PVM4_REG,PVM0_REG
- jmp IND(PVM0_REG)
-
- CONSTS(0)
- END
-
- /*---------------------------------------------------------------------------*/
-
- #undef LBL
- #define LBL(x)MAKE_LBL(54,x)
-
- BEGIN("##atomic-set-car-if-eq?!")
-
- CMPW( IMM(4),DTEMP1)
- BEQS( passed_3args)
-
- WRONG_NB_ARGS(wrong_nb_arg1_trap,3,$entry)
-
- LBL(passed_3args):
- movl PVM0_REG,PVM4_REG
- movl PVM1_REG,DTEMP1
- andw IMM(-8),DTEMP1
- addql IMM(4),DTEMP1
- movl DTEMP1,ATEMP2
-
- LOCK_ATEMP2(lock)
-
- CMPL( DTEMP1,PVM3_REG)
- BNES( not_eq)
-
- movl PVM2_REG,IND(ATEMP2)
- movl IMM(SCM_true),PVM1_REG
- movl PVM4_REG,PVM0_REG
- jmp IND(PVM0_REG)
-
- LBL(not_eq):
- movl DTEMP1,IND(ATEMP2)
- movl FALSE_REG,PVM1_REG
- movl PVM4_REG,PVM0_REG
- jmp IND(PVM0_REG)
-
- CONSTS(0)
- END
-
- /*---------------------------------------------------------------------------*/
-
- #undef LBL
- #define LBL(x)MAKE_LBL(55,x)
-
- BEGIN("##atomic-set-cdr-if-eq?!")
-
- CMPW( IMM(4),DTEMP1)
- BEQS( passed_3args)
-
- WRONG_NB_ARGS(wrong_nb_arg1_trap,3,$entry)
-
- LBL(passed_3args):
- movl PVM0_REG,PVM4_REG
- movl PVM1_REG,DTEMP1
- andw IMM(-8),DTEMP1
- movl DTEMP1,ATEMP2
-
- LOCK_ATEMP2(lock)
-
- CMPL( DTEMP1,PVM3_REG)
- BNES( not_eq)
-
- movl PVM2_REG,IND(ATEMP2)
- movl IMM(SCM_true),PVM1_REG
- movl PVM4_REG,PVM0_REG
- jmp IND(PVM0_REG)
-
- LBL(not_eq):
- movl DTEMP1,IND(ATEMP2)
- movl FALSE_REG,PVM1_REG
- movl PVM4_REG,PVM0_REG
- jmp IND(PVM0_REG)
-
- CONSTS(0)
- END
-
- /*---------------------------------------------------------------------------*/
-
- #undef LBL
- #define LBL(x)MAKE_LBL(550,x)
-
- BEGIN("##make-queue")
-
- CMPW( IMM(1),DTEMP1)
- BEQS( passed_0arg)
-
- WRONG_NB_ARGS(wrong_nb_arg1_trap,0,$entry)
-
- LBL(passed_0arg):
-
- subql IMM(4),HEAP_REG
- movl NULL_REG,PDEC(HEAP_REG)
- movl NULL_REG,PDEC(HEAP_REG)
- movl IMM(QUEUE_SIZE*0x400+(SCM_subtype_QUEUE*8)),PDEC(HEAP_REG)
- lea DISP(HEAP_REG,SCM_type_SUBTYPED),ATEMP1
- movl ATEMP1,PVM1_REG
-
- /* check heap overflow */
-
- CMPL( DISP(PSTATE_REG,SLOT(HEAP_LIM)),HEAP_REG)
- BCCS( ok)
- movl PVM0_REG,PDEC(SP)
- TRAP(heap_alloc1_trap,alloc1,1,1)
- movl PINC(SP),PVM0_REG
- LBL(ok):
-
- jmp IND(PVM0_REG)
-
- CONSTS(0)
- END
-
- /*---------------------------------------------------------------------------*/
-
- #undef LBL
- #define LBL(x)MAKE_LBL(551,x)
-
- BEGIN("##queue-peek-list")
-
- BMIS( passed_1arg)
-
- WRONG_NB_ARGS(wrong_nb_arg1_trap,1,$entry)
-
- LBL(passed_1arg):
-
- movl PVM1_REG,ATEMP2
- movl DISP(ATEMP2,SLOT(QUEUE_HEAD)+4-SCM_type_SUBTYPED),PVM1_REG
- jmp IND(PVM0_REG)
-
- CONSTS(0)
- END
-
- /*---------------------------------------------------------------------------*/
-
- #undef LBL
- #define LBL(x)MAKE_LBL(552,x)
-
- BEGIN("##queue-get-list!")
-
- BMIS( passed_1arg)
-
- WRONG_NB_ARGS(wrong_nb_arg1_trap,1,$entry)
-
- LBL(passed_1arg):
-
- movl PVM1_REG,ATEMP2
- lea DISP(ATEMP2,SLOT(QUEUE_TAIL)+4-SCM_type_SUBTYPED),ATEMP2
-
- movl PVM0_REG,PVM3_REG
- LOCK_ATEMP2(lock)
- movl PVM3_REG,PVM0_REG
-
- CMPL( DTEMP1,NULL_REG)
- BEQS( empty)
-
- movl DISP(ATEMP2,SLOT(QUEUE_HEAD-QUEUE_TAIL)),PVM1_REG
- movl NULL_REG,DISP(ATEMP2,SLOT(QUEUE_HEAD-QUEUE_TAIL))
- movl NULL_REG,IND(ATEMP2)
- jmp IND(PVM0_REG)
-
- LBL(empty):
- movl NULL_REG,PVM1_REG
- movl NULL_REG,IND(ATEMP2)
- jmp IND(PVM0_REG)
-
- CONSTS(0)
- END
-
- /*---------------------------------------------------------------------------*/
-
- #undef LBL
- #define LBL(x)MAKE_LBL(553,x)
-
- BEGIN("##queue-get!")
-
- BMIS( passed_1arg)
-
- WRONG_NB_ARGS(wrong_nb_arg1_trap,1,$entry)
-
- LBL(passed_1arg):
-
- movl PVM1_REG,ATEMP2
- lea DISP(ATEMP2,SLOT(QUEUE_TAIL)+4-SCM_type_SUBTYPED),ATEMP2
-
- movl PVM0_REG,PVM3_REG
- LOCK_ATEMP2(lock)
- movl PVM3_REG,PVM0_REG
-
- CMPL( DTEMP1,NULL_REG)
- BEQS( empty1)
-
- movl DISP(ATEMP2,SLOT(QUEUE_HEAD-QUEUE_TAIL)),PVM1_REG
- movl PVM1_REG,ATEMP1
- movl PDEC(ATEMP1),PVM4_REG
- movl NULL_REG,IND(ATEMP1)
- movl PVM4_REG,DISP(ATEMP2,SLOT(QUEUE_HEAD-QUEUE_TAIL))
- CMPL( PVM4_REG,NULL_REG)
- BEQS( empty2)
- movl DTEMP1,IND(ATEMP2)
- jmp IND(PVM0_REG)
-
- LBL(empty1):
- movl FALSE_REG,PVM1_REG
- LBL(empty2):
- movl NULL_REG,IND(ATEMP2)
- jmp IND(PVM0_REG)
-
- CONSTS(0)
- END
-
- /*---------------------------------------------------------------------------*/
-
- #undef LBL
- #define LBL(x)MAKE_LBL(554,x)
-
- BEGIN("##queue-put!")
-
- BEQS( passed_2args)
-
- WRONG_NB_ARGS(wrong_nb_arg1_trap,2,$entry)
-
- LBL(passed_2args):
-
- movl PVM2_REG,PDEC(HEAP_REG)
- movl HEAP_REG,PVM2_REG
- movl NULL_REG,PDEC(HEAP_REG)
-
- movl PVM1_REG,ATEMP2
- lea DISP(ATEMP2,SLOT(QUEUE_TAIL)+4-SCM_type_SUBTYPED),ATEMP2
-
- movl PVM0_REG,PVM3_REG
- movl PVM1_REG,PVM4_REG
- LOCK_ATEMP2(lock)
- movl PVM4_REG,PVM1_REG
- movl PVM3_REG,PVM0_REG
-
- CMPL( DTEMP1,NULL_REG)
- BEQS( empty)
-
- movl DTEMP1,ATEMP1
- movl PVM2_REG,PDEC(ATEMP1)
- BRAS( unlock)
-
- LBL(empty):
- movl PVM2_REG,DISP(ATEMP2,SLOT(QUEUE_HEAD-QUEUE_TAIL))
-
- LBL(unlock):
- movl PVM2_REG,IND(ATEMP2)
-
- /* check heap overflow */
-
- CMPL( DISP(PSTATE_REG,SLOT(HEAP_LIM)),HEAP_REG)
- BCCS( ok)
- movl PVM0_REG,PDEC(SP)
- TRAP(heap_alloc1_trap,alloc1,1,1)
- movl PINC(SP),PVM0_REG
- LBL(ok):
-
- jmp IND(PVM0_REG)
-
- CONSTS(0)
- END
-
- /*---------------------------------------------------------------------------*/
-
- #undef LBL
- #define LBL(x)MAKE_LBL(56,x)
-
- BEGIN("##make-semaphore")
-
- CMPW( IMM(1),DTEMP1)
- BEQS( passed_0arg)
-
- WRONG_NB_ARGS(wrong_nb_arg1_trap,0,$entry)
-
- LBL(passed_0arg):
-
- movl IMM(1*8),PDEC(HEAP_REG)
- movl NULL_REG,PDEC(HEAP_REG)
- movl NULL_REG,PDEC(HEAP_REG)
- movl IMM(SEMAPHORE_SIZE*0x400+(SCM_subtype_SEMAPHORE*8)),PDEC(HEAP_REG)
- lea DISP(HEAP_REG,SCM_type_SUBTYPED),ATEMP1
- movl ATEMP1,PVM1_REG
-
- /* check heap overflow */
-
- CMPL( DISP(PSTATE_REG,SLOT(HEAP_LIM)),HEAP_REG)
- BCCS( ok)
- movl PVM0_REG,PDEC(SP)
- TRAP(heap_alloc1_trap,alloc1,1,1)
- movl PINC(SP),PVM0_REG
- LBL(ok):
-
- jmp IND(PVM0_REG)
-
- CONSTS(0)
- END
-
- /*---------------------------------------------------------------------------*/
-
- #undef LBL
- #define LBL(x)MAKE_LBL(57,x)
-
- BEGIN("##semaphore-wait")
-
- BMIS( passed_1arg)
-
- WRONG_NB_ARGS(wrong_nb_arg1_trap,1,$entry)
-
- LBL(passed_1arg):
-
- movl PVM1_REG,PVM4_REG
-
- movl PVM4_REG,ATEMP2
- lea DISP(ATEMP2,SLOT(SEMAPHORE_COUNT)+4-SCM_type_SUBTYPED),ATEMP2
-
- movl PVM0_REG,PVM3_REG
- LOCK_ATEMP2(lock1)
- movl PVM3_REG,PVM0_REG
-
- clrl IND(ATEMP2) /* semaphore count now 0 */
-
- tstl DTEMP1 /* semaphore count was 0? */
- BEQS( count_was_0)
-
- movl FALSE_REG,PVM1_REG
- jmp IND(PVM0_REG)
-
- LBL(count_was_0):
-
- /* suspend task on semaphore */
-
- movl PVM0_REG,PDEC(SP)
-
- /* Call ###_kernel.transfer-lazy-tasks-to-heap. */
-
- pea PC_IND(ret1)
- movl CONST(0),ATEMP1
- jmp IND(ATEMP1)
- RETURN(ret1,1,1):
-
- /* Call ###_kernel.transfer-stack-to-heap. */
-
- /* ###_kernel.transfer-lazy-tasks-to-heap has reserved enough */
- /* space, so no GC check required. */
-
- pea PC_IND(ret2)
- movl CONST(1),ATEMP1
- jmp IND(ATEMP1)
- LBL(ret2):
-
- /* Save state of current task. */
-
- movl DISP(PSTATE_REG,SLOT(CURRENT_TASK)),ATEMP1
-
- movl PINC(SP),PVM0_REG
- movl PVM0_REG,DISP(ATEMP1,SLOT(TASK_CONT_RET)+4-SCM_type_SUBTYPED)
- movl PVM2_REG,DISP(ATEMP1,SLOT(TASK_CONT_FRAME)+4-SCM_type_SUBTYPED)
- movl DISP(PSTATE_REG,SLOT(CURRENT_DYN_ENV)),DISP(ATEMP1,SLOT(TASK_CONT_DYN_ENV)+4-SCM_type_SUBTYPED)
- movl FALSE_REG,DISP(ATEMP1,SLOT(TASK_VALUE)+4-SCM_type_SUBTYPED)
-
- movl ATEMP1,PDEC(HEAP_REG)
- movl HEAP_REG,PVM3_REG
- movl NULL_REG,PDEC(HEAP_REG)
-
- /* Final check for availability. */
-
- movl PVM4_REG,ATEMP2
- lea DISP(ATEMP2,SLOT(SEMAPHORE_COUNT)+4-SCM_type_SUBTYPED),ATEMP2
-
- LOCK_ATEMP2(lock2)
-
- tstl DTEMP1 /* semaphore count was 0? */
- BEQS( semaphore_still_not_free)
-
- clrl IND(ATEMP2) /* semaphore count now 0 */
-
- addql IMM(8),HEAP_REG /* discard cons cell */
-
- /* Resume task. */
-
- movl DISP(PSTATE_REG,SLOT(CURRENT_TASK)),ATEMP2
- movl DISP(ATEMP2,SLOT(TASK_CONT_RET)+4-SCM_type_SUBTYPED),DISP(PSTATE_REG,SLOT(PARENT_RET))
- movl DISP(ATEMP2,SLOT(TASK_CONT_FRAME)+4-SCM_type_SUBTYPED),DISP(PSTATE_REG,SLOT(PARENT_FRAME))
- movl DISP(ATEMP2,SLOT(TASK_CONT_DYN_ENV)+4-SCM_type_SUBTYPED),DISP(PSTATE_REG,SLOT(CURRENT_DYN_ENV))
-
- movl PVM4_REG,PVM0_REG
- movl PVM4_REG,PVM1_REG
- movl PVM4_REG,PVM2_REG
- movl PVM4_REG,PVM3_REG
-
- movl DISP(PSTATE_REG,SLOT(BOS_RET)),ATEMP1
- jmp IND(ATEMP1)
-
- LBL(semaphore_still_not_free):
-
- #ifndef butterfly
-
- CMPL( DISP(PSTATE_REG,SLOT(WORKQ_TAIL)),NULL_REG) /* anything else runnable? */
- BNES( no_deadlock)
-
- /* Resume task. */
-
- movl DISP(PSTATE_REG,SLOT(CURRENT_TASK)),ATEMP2
- movl DISP(ATEMP2,SLOT(TASK_CONT_RET)+4-SCM_type_SUBTYPED),DISP(PSTATE_REG,SLOT(PARENT_RET))
- movl DISP(ATEMP2,SLOT(TASK_CONT_FRAME)+4-SCM_type_SUBTYPED),DISP(PSTATE_REG,SLOT(PARENT_FRAME))
- movl DISP(ATEMP2,SLOT(TASK_CONT_DYN_ENV)+4-SCM_type_SUBTYPED),DISP(PSTATE_REG,SLOT(CURRENT_DYN_ENV))
-
- movl PVM4_REG,PVM0_REG
- movl PVM4_REG,PVM1_REG
- movl PVM4_REG,PVM2_REG
- movl PVM4_REG,PVM3_REG
-
- movl DISP(PSTATE_REG,SLOT(BOS_RET)),PVM0_REG
- movl CONST(3),ATEMP1 /* jump to ##exception.deadlock */
- moveq IMM(1),DTEMP1 /* passing 0 argument */
- jmp IND(ATEMP1)
-
- LBL(no_deadlock):
-
- #endif
-
- /* add task to tail of waiting queue */
-
- movl DISP(ATEMP2,SLOT(SEMAPHORE_TAIL-SEMAPHORE_COUNT)),DTEMP1
- CMPL( DTEMP1,NULL_REG)
- BEQS( empty)
- movl DTEMP1,ATEMP1
- movl PVM3_REG,PDEC(ATEMP1)
- BRAS( done)
- LBL(empty):
- movl PVM3_REG,DISP(ATEMP2,SLOT(SEMAPHORE_HEAD-SEMAPHORE_COUNT))
- LBL(done):
- movl PVM3_REG,DISP(ATEMP2,SLOT(SEMAPHORE_TAIL-SEMAPHORE_COUNT))
-
- clrl IND(ATEMP2) /* semaphore count now 0 */
-
- #ifdef MAINTAIN_TASK_STATUS
-
- /* Change task's status to WAITING */
-
- movl DISP(PSTATE_REG,SLOT(CURRENT_TASK)),ATEMP1
- movl NULL_REG,DISP(ATEMP1,SLOT(TASK_STATUS)+4-SCM_type_SUBTYPED)
-
- #endif
-
- moveq IMM(0),PVM1_REG
- movl CONST(2),ATEMP1
- jmp IND(ATEMP1)
-
- CONSTS(4)
- PRIMITIVE("###_kernel.transfer-lazy-tasks-to-heap")
- PRIMITIVE("###_kernel.transfer-stack-to-heap")
- PRIMITIVE("###_kernel.idle")
- PRIMITIVE("##exception.deadlock")
- END
-
- /*---------------------------------------------------------------------------*/
-
- #undef LBL
- #define LBL(x)MAKE_LBL(58,x)
-
- BEGIN("##semaphore-signal")
-
- BMIS( passed_1arg)
-
- WRONG_NB_ARGS(wrong_nb_arg1_trap,1,$entry)
-
- LBL(passed_1arg):
-
- movl PVM1_REG,PVM4_REG
-
- movl PVM4_REG,ATEMP2
- lea DISP(ATEMP2,SLOT(SEMAPHORE_COUNT)+4-SCM_type_SUBTYPED),ATEMP2
-
- movl PVM0_REG,PVM3_REG
- LOCK_ATEMP2(lock1)
- movl PVM3_REG,PVM0_REG
-
- movl DISP(ATEMP2,SLOT(SEMAPHORE_TAIL-SEMAPHORE_COUNT)),DTEMP1
- CMPL( DTEMP1,NULL_REG)
- BNES( restart_task)
-
- movl IMM(1*8),IND(ATEMP2) /* semaphore count now 1 */
-
- movl FALSE_REG,PVM1_REG
- jmp IND(PVM0_REG)
-
- LBL(restart_task):
-
- /* remove first task from waiting queue */
-
- movl DISP(ATEMP2,SLOT(SEMAPHORE_HEAD-SEMAPHORE_COUNT)),ATEMP1
- movl DISP(ATEMP1,SLOT(-1)),PVM1_REG
- movl PVM1_REG,DISP(ATEMP2,SLOT(SEMAPHORE_HEAD-SEMAPHORE_COUNT))
- CMPL( PVM1_REG,NULL_REG)
- BNES( done)
- movl NULL_REG,DISP(ATEMP2,SLOT(SEMAPHORE_TAIL-SEMAPHORE_COUNT))
- LBL(done):
-
- clrl IND(ATEMP2) /* semaphore count now 0 */
-
- #ifdef MAINTAIN_TASK_STATUS
-
- /* Change task's status to READY */
-
- movl IND(ATEMP1),ATEMP2
- movl ATEMP1,DISP(ATEMP2,SLOT(TASK_STATUS)+4-SCM_type_SUBTYPED)
-
- #endif
-
- /* add task to work queue */
-
- movl FALSE_REG,DISP(PSTATE_REG,SLOT(WORKQ_LOCKO))
- LBL(lock_workq):
- tstl DISP(PSTATE_REG,SLOT(WORKQ_LOCKV))
- BNES( lock_workq)
-
- movl DISP(PSTATE_REG,SLOT(WORKQ_TAIL)),ATEMP2
- CMPL( ATEMP2,NULL_REG)
- BNES( non_empty_queue)
- movl ATEMP1,DISP(PSTATE_REG,SLOT(WORKQ_HEAD))
- BRAS( fix_tail)
- LBL(non_empty_queue):
- movl ATEMP1,PDEC(ATEMP2)
-
- LBL(fix_tail):
- movl ATEMP1,DISP(PSTATE_REG,SLOT(WORKQ_TAIL))
-
- movl NULL_REG,PDEC(ATEMP1)
-
- clrl DISP(PSTATE_REG,SLOT(WORKQ_LOCKO))
-
- /* return */
-
- movl FALSE_REG,PVM1_REG
- jmp IND(PVM0_REG)
-
- CONSTS(0)
- END
-
- /*---------------------------------------------------------------------------*/
-
- #undef LBL
- #define LBL(x)MAKE_LBL(59,x)
-
- BEGIN("##legitimacy-barrier")
-
- CMPW( IMM(1),DTEMP1)
- BEQS( passed_0arg)
-
- WRONG_NB_ARGS(wrong_nb_arg1_trap,0,$entry)
-
- LBL(passed_0arg):
- movl DISP(PSTATE_REG,SLOT(CURRENT_TASK)),ATEMP1
- movl DISP(ATEMP1,SLOT(TASK_LEGIT)+4-SCM_type_SUBTYPED),PVM1_REG
-
- /* touch legitimacy placeholder */
-
- btst PVM1_REG,PLACEHOLDER_REG
- BEQS( touch)
- jmp IND(PVM0_REG)
-
- LBL(touch):
- movl PVM1_REG,ATEMP2
- movl DISP(ATEMP2,SLOT(PH_VALUE)-SCM_type_PLACEHOLDER),PVM1_REG
- CMPL( ATEMP2,PVM1_REG)
- BNES( determined)
-
- LOG(EVENT_TOUCH_UNDET,log1)
-
- /* legitimacy placeholders can be determined to placeholders, so must chase */
-
- movl PVM0_REG,PDEC(SP)
- lea PC_IND(ret),PVM0_REG
- movl CONST(0),ATEMP1
- jmp IND(ATEMP1) /* jump to ###_kernel.touch */
- RETURN(ret,1,1):
- movl PINC(SP),PVM0_REG
- LBL(determined):
- btst PVM1_REG,PLACEHOLDER_REG
- BEQS( touch)
-
- jmp IND(PVM0_REG)
-
- CONSTS(1)
- PRIMITIVE("###_kernel.touch")
- END
-
- /*---------------------------------------------------------------------------*/
-
- #undef LBL
- #define LBL(x)MAKE_LBL(60,x)
-
- BEGIN("##sequentially")
-
- BMIS( passed_1arg)
-
- WRONG_NB_ARGS(wrong_nb_arg1_trap,1,$entry)
-
- LBL(passed_1arg):
-
- movl PVM0_REG,PDEC(SP)
-
- /* Call ###_kernel.transfer-lazy-tasks-to-heap. */
-
- CMPL( DISP(PSTATE_REG,SLOT(LTQ_HEAD)),LTQ_TAIL_REG)
- BEQS( tasks_transferred)
-
- movl PVM1_REG,PDEC(SP)
- pea PC_IND(ret1)
- movl CONST(0),ATEMP1
- jmp IND(ATEMP1)
- RETURN(ret1,2,1):
- movl PINC(SP),PVM1_REG
- moveq IMM(0),PVM3_REG
-
- LBL(tasks_transferred):
-
- movl PVM1_REG,ATEMP2
-
- /* Remove tasks from workq */
-
- movl FALSE_REG,DISP(PSTATE_REG,SLOT(WORKQ_LOCKO))
- LBL(lock_workq1):
- tstl DISP(PSTATE_REG,SLOT(WORKQ_LOCKV))
- BNES( lock_workq1)
-
- movl DISP(PSTATE_REG,SLOT(WORKQ_HEAD)),PDEC(SP)
-
- movl NULL_REG,DISP(PSTATE_REG,SLOT(WORKQ_HEAD))
- movl NULL_REG,DISP(PSTATE_REG,SLOT(WORKQ_TAIL))
-
- clrl DISP(PSTATE_REG,SLOT(WORKQ_LOCKO))
-
- /* Call procedure */
-
- lea PC_IND(ret2),PVM0_REG
- moveq IMM(1),DTEMP1
- jmp IND(ATEMP2)
-
- RETURN(ret2,2,1):
-
- /* Restore tasks to workq */
-
- movl PINC(SP),PVM2_REG
-
- btst PVM2_REG,PAIR_REG /* pair? */
- BNES( done)
-
- movl PVM2_REG,DTEMP1 /* get tail */
- LBL(loop):
- movl DTEMP1,ATEMP2
- movl PDEC(ATEMP2),DTEMP1
- btst DTEMP1,PAIR_REG
- BEQS( loop)
-
- movl FALSE_REG,DISP(PSTATE_REG,SLOT(WORKQ_LOCKO))
- LBL(lock_workq2):
- tstl DISP(PSTATE_REG,SLOT(WORKQ_LOCKV))
- BNES( lock_workq2)
-
- CMPL( DISP(PSTATE_REG,SLOT(WORKQ_TAIL)),NULL_REG)
- BNES( non_empty_queue)
- movl NULL_REG,PINC(ATEMP2)
- movl ATEMP2,DISP(PSTATE_REG,SLOT(WORKQ_TAIL))
- BRAS( fix_head)
- LBL(non_empty_queue):
- movl DISP(PSTATE_REG,SLOT(WORKQ_HEAD)),PINC(ATEMP2)
- LBL(fix_head):
- movl PVM2_REG,DISP(PSTATE_REG,SLOT(WORKQ_HEAD))
-
- clrl DISP(PSTATE_REG,SLOT(WORKQ_LOCKO))
-
- LBL(done):
- rts
-
- CONSTS(1)
- PRIMITIVE("###_kernel.transfer-lazy-tasks-to-heap")
- END
-
- /*---------------------------------------------------------------------------*/
-
- #undef LBL
- #define LBL(x)MAKE_LBL(61,x)
-
- BEGIN("###_kernel.startup")
-
- /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
-
- /* Save C's context: */
-
- movl CONST(0),REG(a1)
- #ifndef MIN_C_CONTEXT
- movl REG(d2),DISP(REG(a1),C_D2)
- movl REG(d3),DISP(REG(a1),C_D3)
- movl REG(d4),DISP(REG(a1),C_D4)
- movl REG(d5),DISP(REG(a1),C_D5)
- movl REG(d6),DISP(REG(a1),C_D6)
- movl REG(d7),DISP(REG(a1),C_D7)
- movl REG(a2),DISP(REG(a1),C_A2)
- movl REG(a3),DISP(REG(a1),C_A3)
- movl REG(a4),DISP(REG(a1),C_A4)
- #endif
- movl REG(a5),DISP(REG(a1),C_A5)
- movl REG(a6),DISP(REG(a1),C_A6)
- movl SP,DISP(REG(a1),C_SP)
-
- /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
-
- /* Get parameters: */
-
- movl DISP(SP,4),TABLE_REG /* always = ptr to glob/code table */
- movl DISP(SP,8),PSTATE_REG /* always = ptr to processor state */
-
- movl DISP(SP,12),DTEMP1 /* init 68881 coprocessor */
- BEQS( no_68881)
- fmovel IMM(0),FPSR
- fmovel IMM(0),FPCR
- LBL(no_68881):
-
- /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
-
- /* Setup registers: */
-
- moveq IMM(0),INTR_TIMER_REG
-
- movl IMM(SCM_null),NULL_REG
- movl IMM(SCM_false),FALSE_REG
-
- movl DISP(PSTATE_REG,SLOT(HEAP_PTR)),HEAP_REG
-
- /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
-
- /* Setup stack structure: */
-
- movl DISP(PSTATE_REG,SLOT(STACK_BOT)),DTEMP1
- addl IMM(SLOT(STACK_ALLOCATION_FUDGE)),DTEMP1
- addl DISP(PSTATE_REG,SLOT(STACK_MARGIN)),DTEMP1
- movl DTEMP1,DISP(PSTATE_REG,SLOT(STACK_LIM))
-
- movl IMM(-1),DISP(PSTATE_REG,SLOT(INTR_FLAG))
-
- movl DISP(PSTATE_REG,SLOT(STACK_PTR)),SP
- movl DISP(PSTATE_REG,SLOT(LTQ_TAIL)),LTQ_TAIL_REG
-
- /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
-
- /* Setup 'bottom of stack' return address: */
-
- lea PC_IND(bos_ret),PVM0_REG
- movl PVM0_REG,DISP(PSTATE_REG,SLOT(BOS_RET))
-
- /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
-
- /* Start processors: */
-
- MAKE_TEMP_TASK
-
- movl DISP(PSTATE_REG,SLOT(ID)),DTEMP1
- BEQS( processor0)
-
- /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
-
- /* Startup other processors: */
-
- moveq IMM(0),PVM1_REG
- movl CONST(1),ATEMP1
- jmp IND(ATEMP1)
-
- /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
-
- /* Startup processor 0: */
-
- LBL(processor0):
-
- /* Make root task. */
-
- clrl PDEC(HEAP_REG)
- clrl PDEC(HEAP_REG)
- movl PSTATE_REG,PDEC(HEAP_REG)
- clrl PDEC(HEAP_REG)
- clrl PDEC(HEAP_REG)
- movl IMM(SCM_true),PDEC(HEAP_REG)
- clrl PDEC(HEAP_REG)
- clrl PDEC(HEAP_REG)
- clrl PDEC(HEAP_REG)
- movl IMM(TASK_SIZE*0x400+(SCM_subtype_TASK*8)),PDEC(HEAP_REG)
- lea DISP(HEAP_REG,SCM_type_SUBTYPED),ATEMP1
-
- movl ATEMP1,DISP(PSTATE_REG,SLOT(CURRENT_TASK))
-
- /* Make root continuation. */
-
- subql IMM(4),HEAP_REG
- movl FALSE_REG,PDEC(HEAP_REG)
- movl FALSE_REG,PDEC(HEAP_REG)
- movl IMM(2*0x400+SCM_subtype_FRAME*8),PDEC(HEAP_REG)
- lea DISP(HEAP_REG,SCM_type_SUBTYPED),ATEMP2
-
- lea PC_IND(root_continuation),ATEMP1
- movl ATEMP1,DISP(PSTATE_REG,SLOT(PARENT_RET))
- movl ATEMP2,DISP(PSTATE_REG,SLOT(PARENT_FRAME))
- movl NULL_REG,DISP(PSTATE_REG,SLOT(CURRENT_DYN_ENV))
- movl DISP(PSTATE_REG,SLOT(BOS_RET)),PVM0_REG
-
- #ifdef debug
- /*****/ pea PC_IND($entry)
- /*****/ movl PINC(SP),DISP(PSTATE_REG,SLOT(56))
- /*****/ movl DISP(PSTATE_REG,SLOT(BOS_RET)),DISP(PSTATE_REG,SLOT(57))
- /*****/ movl IMM(0),DISP(PSTATE_REG,SLOT(58))
- #endif
-
- /* Clear PVM registers. */
-
- moveq IMM(0),PVM1_REG
- movl PVM1_REG,PVM2_REG
- movl PVM1_REG,PVM3_REG
- movl PVM1_REG,PVM4_REG
-
- LOG(EVENT_WORKING,log1)
-
- movl CONST(2),ATEMP1 /* jump to ##STARTUP proc */
- moveq IMM(1),DTEMP1 /* passing 0 argument */
- jmp IND(ATEMP1)
-
- RETURN(root_continuation,1,1):
- movl CONST(0),REG(a1) /* restore C's registers */
- #ifndef MIN_C_CONTEXT
- movl DISP(REG(a1),C_D2),REG(d2)
- movl DISP(REG(a1),C_D3),REG(d3)
- movl DISP(REG(a1),C_D4),REG(d4)
- movl DISP(REG(a1),C_D5),REG(d5)
- movl DISP(REG(a1),C_D6),REG(d6)
- movl DISP(REG(a1),C_D7),REG(d7)
- movl DISP(REG(a1),C_A2),REG(a2)
- movl DISP(REG(a1),C_A3),REG(a3)
- movl DISP(REG(a1),C_A4),REG(a4)
- #endif
- movl DISP(REG(a1),C_A5),REG(a5)
- movl DISP(REG(a1),C_A6),REG(a6)
- movl DISP(REG(a1),C_SP),SP
-
- rts
-
- /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
-
- RETURN(bos_ret,0,0):
- /* A fs of 0 is a special return point marker. Here it indicates the return */
- /* point in the oldest frame in the stack. */
-
- movl PVM0_REG,DISP(PSTATE_REG,SLOT(TEMP1))
- movl PVM1_REG,DISP(PSTATE_REG,SLOT(TEMP2))
-
- #ifndef MESSAGE_PASSING_STEAL
-
- movl FALSE_REG,DISP(PSTATE_REG,SLOT(STEAL_LOCKO))
- LBL(lock_steal):
- tstl DISP(PSTATE_REG,SLOT(STEAL_LOCKV))
- BNES( lock_steal)
- movl DISP(PSTATE_REG,SLOT(LTQ_HEAD)),LTQ_TAIL_REG
- movl DISP(PSTATE_REG,SLOT(Q_BOT)),ATEMP1
- LBL(loop1):
- clrl PDEC(LTQ_TAIL_REG)
- CMPL( ATEMP1,LTQ_TAIL_REG)
- BNES( loop1)
- #endif
-
- RESET_STACK
-
- /* After RESET_STACK, ATEMP1 = DEQ_TAIL */
-
- #ifdef debug
- /*****/ movl DISP(PSTATE_REG,SLOT(PARENT_FRAME)),PDEC(SP)
- /*****/ movl DISP(PSTATE_REG,SLOT(PARENT_RET)),PDEC(SP)
- /*****/ movl DISP(PSTATE_REG,SLOT(56)),PDEC(SP)
- /*****/ movl DISP(PSTATE_REG,SLOT(57)),PDEC(SP)
- /*****/ movl DISP(PSTATE_REG,SLOT(58)),PDEC(SP)
- #endif
-
- movl DISP(PSTATE_REG,SLOT(PARENT_FRAME)),PVM0_REG
-
- subql IMM(SCM_type_SUBTYPED),PVM0_REG
- movl PINC(PVM0_REG),PVM1_REG
- lsrl IMM(8),PVM1_REG
-
- LBL(wait):
- movl PINC(PVM0_REG),DISP(PSTATE_REG,SLOT(PARENT_FRAME))
- BNES( copy_frame)
- subql IMM(4),PVM0_REG
- BRAS( wait)
- LBL(copy_frame):
-
- /* copy frame */
-
- #ifdef RESTORE_PARENT_USING_BTRANSFER
-
- broken...
-
- subql IMM(4),PVM1_REG /* PVM1_REG = length of frame */
- subl PVM1_REG,SP /* allocate space on stack */
- movl SP,DTEMP1
- BTRANSFER(copy)
-
- #else
-
- #ifdef debug
- /*****/ addw IMM(5*4),SP
- #endif
-
- movl SP,DTEMP1
- subql IMM(4),PVM1_REG /* PVM1_REG = length of frame */
- subl PVM1_REG,SP /* allocate space on stack */
- movl SP,ATEMP2
-
- lsrl IMM(2),PVM1_REG
- subql IMM(1),PVM1_REG
- LBL(loop3):
- movl PINC(PVM0_REG),PINC(ATEMP2)
- DBRA( PVM1_REG,loop3)
-
- #endif
-
- /* Scan each frame of continuation... */
-
- movl DISP(PSTATE_REG,SLOT(PARENT_RET)),PVM0_REG
- movl SP,PVM1_REG
-
- #ifdef debug
- /*****/ movl DISP(PSTATE_REG,SLOT(PARENT_FRAME)),PDEC(SP)
- /*****/ movl DISP(PSTATE_REG,SLOT(PARENT_RET)),PDEC(SP)
- /*****/ movl DISP(PSTATE_REG,SLOT(56)),PDEC(SP)
- /*****/ movl DISP(PSTATE_REG,SLOT(57)),PDEC(SP)
- /*****/ movl DISP(PSTATE_REG,SLOT(58)),PDEC(SP)
- #endif
-
-
- LBL(loop4):
- movl PVM1_REG,ATEMP2
- moveq IMM(0),PVM1_REG
- movw DISP(PVM0_REG,-6),PVM1_REG /* get fs */
- BGTS( normal_ret)
- BEQS( dyn_env_ret)
- movl ATEMP2,PINC(LTQ_TAIL_REG) /* push task marker */
- andw IMM(0x7fff),PVM1_REG
- BRAS( normal_ret)
- LBL(dyn_env_ret):
- movl ATEMP2,PDEC(ATEMP1) /* push dyn env marker */
- movw IMM(SLOT(DYN_ENV_FS)),PVM1_REG
- LBL(normal_ret):
- addl ATEMP2,PVM1_REG
- addw DISP(PVM0_REG,-4),ATEMP2 /* add link */
- movl IND(ATEMP2),PVM0_REG
- CMPL( DTEMP1,PVM1_REG)
- BNES( loop4)
-
- movl DISP(PSTATE_REG,SLOT(BOS_RET)),IND(ATEMP2)
-
- /* Slots of LTQ and DEQ are in reverse order, so reverse them... */
-
- movl ATEMP1,DISP(PSTATE_REG,SLOT(DEQ_TAIL))
- movl DISP(PSTATE_REG,SLOT(DEQ_HEAD)),ATEMP2
- LBL(loop5):
- movl PDEC(ATEMP2),DTEMP1
- CMPL( ATEMP2,ATEMP1)
- BCCS( deq_reversed)
- movl IND(ATEMP1),IND(ATEMP2)
- movl DTEMP1,PINC(ATEMP1)
- BRAS( loop5)
- LBL(deq_reversed):
-
- movl LTQ_TAIL_REG,ATEMP1
- movl DISP(PSTATE_REG,SLOT(LTQ_HEAD)),ATEMP2
- LBL(loop6):
- movl PDEC(ATEMP1),DTEMP1
- CMPL( ATEMP1,ATEMP2)
- BCCS( ltq_reversed)
- movl IND(ATEMP2),IND(ATEMP1)
- movl DTEMP1,PINC(ATEMP2)
- BRAS( loop6)
- LBL(ltq_reversed):
-
- /* Setup correct return address for parent and return to restored cont */
-
- movl DISP(PSTATE_REG,SLOT(PARENT_RET)),ATEMP2
- movl PVM0_REG,DISP(PSTATE_REG,SLOT(PARENT_RET))
-
- #ifndef MESSAGE_PASSING_STEAL
- clrl DISP(PSTATE_REG,SLOT(STEAL_LOCKO))
- #endif
-
- #ifdef debug
- /*****/ addw IMM(5*4),SP
- /*****/ pea PC_IND($entry)
- /*****/ movl PINC(SP),DISP(PSTATE_REG,SLOT(56))
- /*****/ movl ATEMP2,DISP(PSTATE_REG,SLOT(57))
- /*****/ movl IMM(0),DISP(PSTATE_REG,SLOT(58))
- #endif
-
- movl DISP(PSTATE_REG,SLOT(TEMP1)),PVM0_REG
- movl DISP(PSTATE_REG,SLOT(TEMP2)),PVM1_REG
-
- movl PVM1_REG,DTEMP1 /* Required for the case of a return from a touch of d0 */
-
- jmp IND(ATEMP2)
-
- CONSTS(3)
- PRIMITIVE("###_kernel")
- PRIMITIVE("###_kernel.idle")
- PRIMITIVE("##startup")
- END
-
- /*---------------------------------------------------------------------------*/
-
- OBJECT_FILE_END
-